我正在使用find并获取要grep通过的文件列表。如何将列表通过管道发送到grep

#1 楼

好吧,与写入stdout的任何命令一起使用的通用情况是使用xargs,这将使您可以将任意数量的命令行参数附加到命令的末尾:
$ find … | xargs grep 'search'

或嵌入请在您的grep行中使用反引号或$()命令,该命令将运行命令并替换其输出:
$ grep 'search' $(find …)

请注意,如果文件名包含空格或某些其他“怪异”命令,则这些命令将不起作用字符”(对于xargs为\'",对于\[*?$(find …))。但是,在find的特定情况下,内置了对给定参数执行程序的功能:
$ find … -exec grep 'search' {} \;

-exec;之间的所有内容都是要执行的命令; {}被替换为find找到的文件名。这将为每个文件执行单独的grep;由于grep可以接受许多文件名并全部搜索,因此您可以将;更改为+,以告知find将所有匹配的文件名立即传递给grep
$ find … -exec grep 'search' {} \+


评论


应该注意的是,前两种形式不适用于包含空格的文件名。

– Enzotib
2011年9月7日19:09

我更喜欢找到... -type f -print0 | xargs -r0 grep'搜索'/ dev / null。 QED。尽管-exec +非常有效,但并非所有版本的find都存在。

–Arcege
2011年9月7日19:11

遗憾的是,我无法检查您是否正确3次。

–詹姆斯
2011年9月7日19:43

我建议使用-exec,而不是xargs。如果在find中使用-exec,它将仅创建一个shell来grep内容。如果使用xargs,它将创建两个shell:一个用于查找,另一个用于xargs。

–user14470
2012年1月18日在18:32



通过实验,我发现$ find…-exec grep'search'{} \ +形式是最快的。

– gogoud
16年11月14日上午10:32

#2 楼

grep的某些版本(例如在非嵌入式Linux或BSD或Mac OS X上)具有-r选项以进行递归搜索。在OpenBSD上,使用-R(下面的示例中没有--exclude)。这涵盖了findgrep的简单组合。 。一些较旧的-R实现不支持-execfind;在这些系统上,请使用grep而不是find(这将对每个文件调用一次-exec,因此速度会较慢,但结果将相同)。请注意+技巧,即使恰好在单个文件上调用它,也会使;显示文件名(GNU grep和FreeBSD / NetBSD / OSX grep具有+选项,可以达到相同的效果)。

find . -type f -name '*.o' -prune -o -exec grep 'needle' /dev/null {} +
grep -r --exclude='*.o' 'needle' .


评论


GNU grep具有-H选项以始终打印文件名。

– Enzotib
2011年9月8日下午12:11

#3 楼

例如:
搜索名称中带有“ Delay”且在所找到文件内部某处具有“ Create”的文件
find . | grep Delay | xargs grep 'Create'

,如果找到了某些内容,则应显示每行写有“创建”一词的地方。

#4 楼

find ... | while read line; do grep <regex> "$line"; done


评论


尽管您的方法非常简单,但请花时间添加最少的解释。另外,请注意,这与大多数其他答案存在相同的问题,因为它依赖于解析find的输出,由于文件名中的特殊字符可能存在问题,因此应避免使用find(尽管可以根据shell进行修复)用过的)。

– AdminBee
20 Sep 18 '13:13