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' {} \+
#2 楼
grep
的某些版本(例如在非嵌入式Linux或BSD或Mac OS X上)具有-r
选项以进行递归搜索。在OpenBSD上,使用-R
(下面的示例中没有--exclude
)。这涵盖了find
与grep
的简单组合。 。一些较旧的-R
实现不支持-exec
…find
;在这些系统上,请使用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
评论
应该注意的是,前两种形式不适用于包含空格的文件名。
– 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