通配符扩展的工作方式有一个微妙之处。切换到不包含 .jpg 文件的目录并键入
echo *.jpg
Run Code Online (Sandbox Code Playgroud)
它会输出
*.jpg
Run Code Online (Sandbox Code Playgroud)
特别是,字符串 *.jpg 保持不变。但是,如果您切换到包含 .jpg 文件的目录,例如假设我们有两个文件:image1.jpg 和 image2.jpg,则 echo *.jpg 命令将不会输出
image1.jpg image2.jpg
Run Code Online (Sandbox Code Playgroud)
并且 *.jpg 被扩展。
如果你输入
find . -name *.jpg
Run Code Online (Sandbox Code Playgroud)
并且在您键入此内容时所在的目录中没有 .jpg 文件,然后 find 将接收参数“.”、“-name”和“*.jpg”。但是,如果您在包含 .jpg 文件的目录中键入此命令,例如 image1.jpg 和 image2.jpg,则 find 将收到参数“.”、“-name”、“image1.jpg”和“image2.jpg” ",所以实际上会运行命令
find . -name image1.jpg image2.jpg
Run Code Online (Sandbox Code Playgroud)
和 find 会抱怨。如果省略引号,真正令人困惑的是是否只有一个 .jpg 文件(比如 image1.jpg)。然后通配符扩展将导致
find . -name image1.jpg
Run Code Online (Sandbox Code Playgroud)
find 命令将查找所有基本名称为 image1.jpg 的文件。
旁白:这确实导致了一个有用的 bash 习惯用法,用于查看是否有任何文件与给定模式匹配:
if [ "$(echo *.jpg)" = "*.jpg" ]; then
# *.jpg has no matches
else
# *.jpg has matches
fi
Run Code Online (Sandbox Code Playgroud)
但请注意,如果当前目录中有一个名为“*.jpg”的文件,这将不起作用。为了更加防水,你可以这样做
if [ "$(echo *.jpg)" = "*.jpg" ] && [ ! -e "*.jpg" ]; then
# *.jpg has no matches
else
# *.jpg has matches
fi
Run Code Online (Sandbox Code Playgroud)
(虽然与问题没有直接关系,但我添加了这个,因为它说明了通配符扩展如何工作的一些方面。)