早在 1990 年代,我会使用“ ”来表示 MS-DOS 中的任何文件名,但现在*.*
我看到更多脚本只使用“ ”。使用哪一个实际上有什么区别吗?*
答案1
文件名和扩展名已单场自从 Windows 95 和 NT 3.5 引入了“长文件名”支持,通配符匹配一次针对整个文件名进行。因此,即使文件名中没有点(对于文件来说可能很少见,但对于文件夹/目录来说却很常见),乍一看*.*
也不会真正匹配这样的文件。
旧脚本使用*.*
将要由于兼容性代码,仍然可以工作 – 如果通配符以 结尾.*
,则该部分是被操作系统忽略。(所以如果你想专门匹配文件和一个扩展,我想你会需要*.?*
它。
但这不是你应该依赖的东西;如果你正在为现代 Windows 版本编写脚本,请遵循它们的约定,不是MS-DOS 约定。(请注意,从 Windows NT 开始,.bat 脚本不是不再由 MS-DOS 解释,而是由cmd.exe
本机 Win32 程序解释。
在 Linux 和其他各种 Unixen 上,名称和扩展名从来就不是分开的,而且不是任何特殊的魔法都可以发挥*.*
作用,所以这*
是唯一有意义的选择。
答案2
也许值得一提的是,unixy/posixy shell,如 bourne shell、bash、ksh、zsh 等,会进行通配符扩展(包括通配符,如*
、?
、[range]
和[!range]
其他扩展,如括号和扩展通配符),以编译参数列表前命令被执行。因此,这个扩展是由 shell 完成的,而不是由这些可能作为参数的命令完成的。
即 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
在 CMD 中情况并非如此(并且对于 powershell 实用程序也类似),因为它将 glob 字符逐字逐句地传递给执行的命令 - 因此扩展是命令/实用程序的责任,而不是 shell 的责任。因此,最终,*.*
或*
意味着什么取决于实用程序,让它符合(或不符合)惯例 - 这就是为什么 CMD 的实用程序dir *.*
也匹配(可以说是不正确的,但仍保留了预期)没有扩展名的文件。
我认为可以这样总结。
- 在 CMD 下,它取决于实用程序。
- 在 PowerShell 中,利用WildCardPattern 类将提供一致的 posixy 行为子集。