![grep中的“*.pl”和*.pl有什么区别?为什么引用会改变结果?](https://linux22.com/image/33740/grep%E4%B8%AD%E7%9A%84%E2%80%9C*.pl%E2%80%9D%E5%92%8C*.pl%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%9F%E4%B8%BA%E4%BB%80%E4%B9%88%E5%BC%95%E7%94%A8%E4%BC%9A%E6%94%B9%E5%8F%98%E7%BB%93%E6%9E%9C%EF%BC%9F.png)
有什么区别:
grep "string" . -r --include *.pl
和
grep "string" . -r --include "*.pl"
后者包含子目录中的文件,而前者则不包含。为什么?
答案1
(星*
号或星号)是一个特殊字符,通常由 shell 在给出命令之前对其进行解释。它(通常)扩展到所有文件名,除了带有前导点的文件名。请参阅关于模式匹配的 bash 手册了解更多信息。
如果将星号放在引号中,则 shell 不会解释该星号,而是将其逐字提供给命令。
举例说明。引用的一位:
grep "string" . -r --include "*.pl"
这里将收到带有参数的grep
选项。这是一个以 字符 开头的 4 个字符的字符串。该字符串的作用完全取决于.在这种情况下意味着仅考虑与 glob 匹配的文件。--include
*.pl
*
grep
grep
--include
*.pl
据我所知,gnu grep 在幕后使用与 gnu bash 相同的模式匹配库。这意味着它将包含与 所示相同的文件echo *.pl
。
未引用的:
grep "string" . -r --include *.pl
*.pl
这里,shell在执行命令之前将首先展开 glob 。 glob 将扩展到所有以.pl
.
假设有文件foo.pl
、bar.pl
和baz.pl
。展开 glob 后,命令行如下所示:
grep "string" . -r --include foo.pl bar.pl baz.pl
这里将接收带有参数的grep
选项,后跟选项和。--include
foo.pl
bar.pl
baz.pl
--include foo.pl
指示 grep 仅考虑与模式匹配的文件foo.pl
。由于模式中没有通配符(没有星号),唯一匹配的文件将是名为foo.pl
.
选项bar.pl
和baz.pl
指示 grep 也在这些文件中搜索。但由于它们与模式不匹配,因此foo.pl
它们将根据前一个的要求被忽略--include
。
答案2
不同之处在于,如果您不引用模式 ( *.pl
),它会被 shell 扩展。例如,如果您grep
在包含名为 的文件的目录中运行foo.pl
,由于 是*pl
由 shell 展开的,因此grep
实际看到的是:
grep "string" . -r --include foo.pl
由于您告诉它仅包含foo.pl
它,因此它只会搜索该一个文件。
如果你引用你的模式,shell 会不是展开它并grep
得到正确的命令,即
grep "string" . -r --include *pl