运行 使用 --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
(以及 ksh
和 zsh
),您必须具有:
a list of 至少 2 项,用 ,
分隔;例如{py,txt}
,扩展为 2 个参数,py
和 txt
.
或者,一个范围的项目由两个端点组成,用..
分隔;例如,{1..3}
,它扩展为 3 个参数,1
、2
和 3
.
因此,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
这是 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
, thegrep
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
(以及 ksh
和 zsh
),您必须具有:
a list of 至少 2 项,用
,
分隔;例如{py,txt}
,扩展为 2 个参数,py
和txt
.或者,一个范围的项目由两个端点组成,用
..
分隔;例如,{1..3}
,它扩展为 3 个参数,1
、2
和3
.
因此,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