关于双引号的困惑

A.C*_*Cho 4 shell find quoting wildcards

我在使用命令时了解到,双引号将除 $、`、\ 之外的所有内容都视为字符。

但是,当使用命令 likefind -type f -name "*.jpg" *.jpg在双引号内时。然后,这意味着我们想要将*.视为一个角色。因此,该find命令应该输出具有名称的常规文件*.jpg,而不是实现路径名扩展。

如果我们想做路径名扩展,我想我必须做类型命令find -type f -name *.jpg(没有双引号)。

但是,结果是一样的。为什么在这个命令中使用双引号?

Joh*_*sup 5

通配符扩展的工作方式有一个微妙之处。切换到不包含 .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)

(虽然与问题没有直接关系,但我添加了这个,因为它说明了通配符扩展如何工作的一些方面。)