运行 使用 --include 选项进行 grep 时出现奇怪的问题

Weird issue when running grep with the --include option

这是 bash shell 处的代码。如果不是这样,应该如何指定文件掩码?我希望这两个命令都能找到搜索表达式,但它没有发生。在这个例子中,我事先知道我更愿意将搜索限制在 python 个源代码文件中,因为不合格的搜索是愚蠢的浪费时间。

因此,这按预期工作:

grep -rni '/home/ga/projects' -e 'def Pr(x,u,v)'

/home/ga/projects/anom/anom.py:27:def Pr(x,u,v): blah, blah, ...

但这行不通:

grep --include=\*.{py} -rni '/home/ga/projects' -e 'def Pr(x,u,v)'

我正在使用 GNU grep 2.16 版。

像这样尝试(使用 quotes 是安全的;也比 backslash 转义恕我直言更好的可读性:

grep --include='*.py' ...

您的 \*.{py} 大括号扩展 用法完全 grep 不受支持。请参阅下面的评论以了解有关此的完整调查。郑重声明,将导致的括号大战归咎于 this answer ;)

顺便说一句,大括号扩展在 Bash 中通常工作正常。有关详细信息,请参阅


确认。作为替代方案,您可以考虑从现在开始改用 ack。它是一个类似于 grep 的工具,但针对程序员进行了全面优化。

它非常适合您的工作。关于它的一个很好的引用

Every once in a while something comes along that improves an idea so much, you can't ignore it. Such a thing is ack, the grep replacement.

由于大括号“{}”,您的命令失败。它将在文件名中搜索它。您可以创建一个文件,例如 'myscript.{py}' 来说服自己。您会看到它会出现在结果中。

正确的选项参数应该是 '*.py' 或等效的 \*.py。无论哪种方式都会保护它免受 shell.

的(错误)解释

另一方面,我只能建议对此类工作使用命令 find :

find /home/ga/projects -regex '.*\.py$' -exec grep -e "def Pr(x,u,v)" {} +

这将保护您免受难以理解的 shell 行为。

--include=\*.{py} 看起来像是 失败的尝试 来使用 大括号扩展 ( 未加引号 {...} 表达式)。

然而,对于 brace expansion 发生在 bash(以及 kshzsh),您必须具有:

  • a list of 至少 2 项,用 , 分隔;例如{py,txt},扩展为 2 个参数,pytxt.

  • 或者,一个范围的项目由两个端点组成,用..分隔;例如,{1..3},它扩展为 3 个参数,123.

因此,with a single item, simple don't use brace expansion:

--include=\*.py

如果您确实有多个扩展需要考虑,例如 *.py 以及 *.pyc 文件,这里有一个强大的表格来说明潜在的 shell 功能:

'--include=*.'{py,pyc}

此处:

  • 应用大括号扩展 ,因为 {...} 包含 2 项列表。
  • 因为 {...} 直接 跟在 文字 (单引号)字符串 --include=*. 之后,结果大括号扩展 包括 文字部分。
  • 因此,2个参数最终传递给grep,内容如下文字
    • --include=*.py
    • --include=*.pyc