管道将结果找到grep以便快速排除目录

时间:2012-07-19 16:41:16

标签: linux recursion find grep piping

我成功使用find创建当前子目录中所有文件的列表,不包括子目录“cache”中的文件。这是我的第一段代码:

find . -wholename './cach*' -prune -o -print

我现在希望将它传递给grep命令。看起来应该很简单:

find . -wholename './cach*' -prune -o -print | xargs grep -r -R -i "samson"

...但这会返回主要来自缓存目录的结果。我已经尝试删除了xargs引用,但是这可以达到你所期望的,在文件名的文本上运行grep,而不是在文件本身上运行。我的目标是在任何非缓存内容的文件中找到“samson”。

我可能会在这个例子中使用doubled greps解决这个问题,但我很好奇这个单行为什么会这样。我喜欢听到关于修改它的方法的想法,同时仍然使用这两个命令(因为这样做有速度优势)。

(这是在CentOS 5,顺便说一句。)

3 个答案:

答案 0 :(得分:9)

wholename匹配可能是它仍然包含“缓存”文件的原因。如果您在包含“cache”文件夹的目录中执行find命令,它应该可以正常工作。如果没有,请尝试将其更改为-name '*cache*'

此外,您的-r不需要-Rgrep,它告诉它通过目录递归 - 但您正在测试单个文件。

您可以使用管道版或单命令更新命令:

find . -name '*cache*' -prune -o -print0 | xargs -0 grep -il "samson"

find . -name '*cache*' -prune -o -exec grep -iq "samson" {} \; -print

注意,第一个命令中的-l告诉grep“列出文件”而不是匹配的行。第二个-q也是一样的;它告诉grep安静地回复,以便find只打印文件名。

答案 1 :(得分:3)

在find上使用-exec选项,而不是将它们传递给另一个命令。从那里,您可以使用grep "samson" {} \;在列出的每个文件中查找samson。

例如:

find . -wholename './cach*' -prune -o -exec grep "samson" "{}" +

答案 2 :(得分:3)

你告诉grep本身要递归(两次!-r-R是同义词)。由于您传递的参数之一是.(顶级目录),grep正在搜索每个文件(其中一些文件是两次,如果它们在子目录中,则更多)。

如果您要使用findgrep,请执行以下操作:

find . -path './cach*' -prune -o -print0 | xargs -0 grep -i "samson"

使用-print0-0即使文件名包含空格或标点字符,您的脚本也能正常工作。

但是,你可能不需要在这里打扰find,因为GNU grep能够排除目录:

grep -R --exclude-dir='cach*' -i "samson" .

(这也不包括./deeply/nested/directory/cache。如果您只想在顶层排除缓存目录,请像使用find一样。)