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


10

之间有什么区别?
grep "string" . -r --include *.pl

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

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


区别不在grep; 它在外壳中。 grep从来没有看到报价。
通配符

Answers:


17

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

如果用引号引起来,则星号不会被外壳解释,并逐字给出命令。


举例说明。引用一:

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

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

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

未引用的是:

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

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

grep "string" . -r --include foo.pl bar.pl baz.pl

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

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


这是一个很好的观察。我一直想知道为什么grep -r看起来前后不一致,但从来没有注意到,只是当我使用了*
j883376

6

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

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

由于您告诉它仅包含foo.pl它,因此只会搜索该文件。

如果引用模式,shell将不会对其进行扩展并grep获得正确的命令,即

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

peopl不会被扩展*.pl
unxnut

@unxnut好点,答案已编辑。
terdon
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.