如何在有空格的grep输出上执行xargs grep?


8

我正在基于正则表达式搜索文件,然后尝试在这些文件中搜索内容。例如,我有类似

#Find all C++ files that match a certain pattern and then search them
find . -name "*.cpp" | grep "<name regex>" | xargs grep "<content regex>"

我遇到的问题是某些路径中有空格,这会造成混淆xargs。我知道,如果我只是使用find,则可以使用-print0参数(以及上的-0参数xargs)来防止xargs将空格视为定界符。有类似的东西grep吗?

还是我完全以错误的方式解决了这个问题?天真,findgrepxargs grep对我来说很有意义,但我持开放的态度产生相同的结果的其他方法。


2
您可以xargs使用-i参数la 来定位参数,cat sample.txt | grep "pat t ern" | xargs -i grep "{}"大括号告诉它参数的位置。该手册告诉我,-i不建议使用,-I因此也许也值得一看。
dougBTV

Answers:


5

也许使用类似这样的东西(如果是gnu grep)。

grep -r 'content pattern' --include==*.cpp

曼格雷普

--include = GLOB仅搜索基本名称与GLOB匹配的文件(使用--exclude中所述的通配符匹配)

另请参见空定界符的选项。

-Z,--null输出零字节(ASCII NUL字符),而不是通常在文件名后的字符。例如,grep -lZ在每个文件名之后输出一个零字节,而不是通常的换行符。即使存在包含不寻常字符(例如换行符)的文件名,此选项也可以使输出明确。该选项可与find -print0,perl -0,sort -z和xargs -0等命令一起使用,以处理任意文件名,即使是包含换行符的文件名。

-z,--null-data将输入视为一组行,每行以零字节(ASCII NUL字符)而不是换行符结尾。与-Z或--null选项一样,此选项可与sort -z等命令一起使用以处理任意文件名。


请注意,这grep -r include='*.cpp'是一个外壳问题-与特征对齐的w / find . -name '*.cpp' -exec grep -e 'content_pattern' -- {} \;不是w /find . -name '*.cpp' | grep 'name_pattern' | xargs grep 'content_pattern'
mikeserv

4

如果必须跳很多圈,那么xargs的效率反而会丢失。这是一个粗略的解决方法:

find . -iname "*.cpp" | grep "<pattern>" | while read -r x; do grep exa "$x"; done

每当我遇到文件名中的空格问题时,答案就是在变量上使用双引号。


这将为外部grep找到的每一行唯一地运行循环的内部grep。那是很多开销。
亚当·卡兹

3

find做所有的文件名过滤。而不是

find . -name "*.cpp" | grep "foo" | xargs grep 

find . -name "*.cpp" -name "*foo*" -print0 | xargs -0 grep 

如果您想做一些更复杂的事情,例如

find . -name "*.cpp" | egrep "foo|bar" | xargs grep 

你可以做

find . -name "*.cpp" "(" -name "*foo*" -o -name "*bar*" ")" -print0 | xargs -0 grep 

请注意,这些名称甚至对于名称中包含换行符的文件也适用。

而且,如果您需要功能强大的正则表达式,可以使用-regex


2

即使没有GNU工具,这也应该起作用:

#Find all C++ files that match a certain pattern and then search them
find . -name "*.cpp"  | grep "<name regex>" | perl -pe 's/\n/\0/' \
  | xargs -0 grep "<content regex>"

perl调用将换行符替换为空字符,这将允许xargs -0按行而不是按空白解释输入。

使用GNU,您可以删除perl呼叫并将其更改xargs -0 …xargs -d "\n" …

没有perl或GNU?试试吧awk '{printf "%s%c", $0, 0}'


1
如果某些文件名包含换行符,则此操作可能不正确(当然,这是很不常见的情况,但并非不可能)。
dhag 2015年

@dhag关于有一个有效的观点xargs -d "\n"。这是非常不常见的情况,但是如果您无法控制数据并担心它会带来安全风险,请注意输出预期。
亚当·卡兹
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.