grep中的“*.pl”和*.pl有什么区别?为什么引用会改变结果?

Jim*_*Jim 10 shell grep quoting wildcards

有什么区别:
grep "string" . -r --include *.pl

grep "string" . -r --include "*.pl"

后者包括子目录中的文件,而前者不包括。为什么?

les*_*ana 17

*(星形,星号或)是(通常)由shell解释发出命令之前,一个特殊字符。它(通常)扩展到所有文件名,除了那些带有前导点的文件名。有关更多信息,请参阅有关模式匹配bash 手册

如果放在引号中,星号将不会被 shell 解释并逐字提供给命令。


举例说明。引用之一:

grep "string" . -r --include "*.pl"
Run Code Online (Sandbox Code Playgroud)

这里grep将接收--include带有参数的选项*.pl。即以*字符为第一个字符的 4 个字符串。什么grep与字符串所做的是完全由grep。在这种情况下--include意味着只考虑匹配模式的文件*.pl

AFAIK 在幕后 gnu grep 使用与 gnu bash 相同的模式匹配库。

未引用的一个:

grep "string" . -r --include *.pl
Run Code Online (Sandbox Code Playgroud)

在这里,shell 将首先将模式扩展*.pl到所有以.pl. 假设有文件foo.pl,bar.plbaz.pl。展开命令行后如下所示:

grep "string" . -r --include foo.pl bar.pl baz.pl
Run Code Online (Sandbox Code Playgroud)

这里grep将接收--include带有参数的选项foo.pl,后跟选项bar.plbaz.pl--include foo.pl意味着只考虑匹配模式的文件foo.pl。由于模式中没有通配符,唯一匹配的文件将是名为foo.pl.

选项bar.plbaz.pl手段 grep 也将在这些文件中搜索,但由于它们与模式不匹配,foo.pl因此将被忽略。


ter*_*don 6

不同之处在于,如果您不引用模式 ( *.pl),它会被 shell 展开。例如,如果您grep在包含名为 的文件的目录中运行您的文件foo.pl,由于*pl由外壳展开,grep实际看到的是:

grep "string" . -r --include foo.pl
Run Code Online (Sandbox Code Playgroud)

因为你告诉它只包含foo.pl它只会搜索那个文件。

如果您引用您的模式,shell 将不会展开它并grep获得正确的命令,即

 grep "string" . -r --include *pl
Run Code Online (Sandbox Code Playgroud)