CMD:*.* 或只是 *?

Foe*_*ane 47 command-line

早在 1990 年代,我会使用“ *.*”来表示 MS-DOS 中的任何文件名,但*这些天我看到更多的脚本只使用“ ”。它实际上对我使用哪一种有任何影响吗?

use*_*686 65

自从 Windows 95 和 NT 3.5 引入“长文件名”支持以来,文件名和扩展名一直是一个字段,并且通配符匹配是针对整个文件名一次性完成的。因此,您可以拥有一个没有点的文件名(对于文件来说可能很少见,但对于文件夹/目录来说很常见),乍一看*.*实际上与此类文件不匹配。

使用旧脚本*.* 因为兼容性的代码仍然工作-如果用通配符结束.*,这部分是由操作系统忽略。(因此,如果您想将文件扩展名专门匹配,我想您需要这样做*.?*。)

但这不是你应该依赖的东西;如果您正在为现代 Windows 版本编写脚本,请遵循它们的约定,而不是MS-DOS 约定。(请注意,从 Windows NT 开始,.bat 脚本不再由 MS-DOS 解释,而是由cmd.exe本机 Win32 程序解释。)


在 Linux 和其他各种 Unixen 上,名称和扩展名从一开始就从未分开,并且没有任何特殊的魔法可以*.*工作,因此*是唯一有意义的选择。

  • “让我们为每个人打破数百万个现有的批处理脚本!耶!” - 从来没有微软开发人员 (50认同)
  • “让我们更难过滤带有扩展名的文件!耶!” - 匿名微软开发人员 (14认同)
  • OP 是关于 Windows 的,但是由于您提到了 Linux:在某些 shell(例如 Bash)中,`*` 确实([默认](http://mywiki.wooledge.org/glob#dotglob))不是匹配隐藏的文件名(以`.` 开头)。 (8认同)
  • 对于“操作系统级别”的某些值......它实际上也是 Windows 中的一个 shell(资源管理器)概念——内核不关心可执行文件上的 .exe,也不关心其他任何东西。可以争论 Windows 资源管理器是否比 Linux 中的 Nautilus 更“操作系统级别”。 (4认同)
  • ISTR 指出,在某些旧版本的 DOS 上,`*` 只会匹配_没有_扩展名的文件名。与两者兼容的“安全”方法是使用`**`。 (3认同)

小智 11

这也许值得一提的是,unixy /喜欢的Bourne shell时,bash和ksh,zsh的等posixy贝壳做通配符扩展(全域字符,例如*?[range][!range]和其他扩展像括号和扩展水珠)编译的参数列表的命令被执行。所以这个扩展是由 shell 完成的,而不是这些可能是其参数的命令。

即外壳负责什么**.*扩展到

 $ ls
 file.csv  file.doc  file.pdf  file.txt  file.xlsx  zz-file-without-extension

 $ (set -xv; foo *)   # is actually expanded to the following
   + foo file.csv file.doc file.pdf file.txt file.xlsx zz-file-without-extension

 $ (set -xv; foo *.*)  # note this does not match `zz-file-without-extension`
   + foo file.csv file.doc file.pdf file.txt file.xlsx
Run Code Online (Sandbox Code Playgroud)

这不是 CMD 的情况(对于 powershell 实用程序也是如此),因为它将全局字符逐字传递给执行的命令 - 因此扩展是命令/实用程序的责任,而不是 shell。所以最终,什么*.**意味着什么留给实用程序让它符合(或不符合)约定——这就是为什么 CMD 的实用程序dir *.*也匹配(可以说是不正确但保留期望)没有扩展名的文件。

我相信这样总结是安全的。

  • 在 CMD 下,它取决于实用程序。
  • 在 PowerShell 下,使用WildCardPattern类的实用程序将提供一致的 posixy 行为子集。

  • @grawity 更准确地说,过滤是由 Windows 上的文件系统驱动程序完成的。这在网络文件系统上特别有用(尤其是当您可以运行 8 kb 线路到远程文件系统时),但这也意味着您不能进行任意搜索以及明确支持的搜索。Raymond Chen 的博客中多次探讨了其含义。`FindFirstFile` 本身是用户模式(kernel32.dll 和 ntdll.dll 都是用户模式库 - 它是 Win32 子系统的一部分,而不是内核),但它实际上并没有做太多事情。 (3认同)