如何对包含空格的 grep 输出执行 xargs grep?

如何对包含空格的 grep 输出执行 xargs grep?

我正在基于正则表达式搜索文件,然后尝试搜索这些文件的内容。所以,举例来说,我有类似的东西

#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

或者我完全以错误的方式处理这个问题?天真地,findto greptoxargs grep对我来说是有意义的,但我对产生相同结果的其他方法持开放态度。

答案1

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

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

人 grep

--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 等命令一起使用来处理任意文件名。

答案2

如果你必须跳过很多圈,那么 xargs 的效率无论如何都会损失。这是一种粗略的解决方法:

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

每次我遇到文件名中的空格问题时,答案都是变量上的双引号。

答案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.

答案4

即使没有 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" …

没有perlGNU?试试awk '{printf "%s%c", $0, 0}'吧。

相关内容