10

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

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

我现在希望将其通过管道传输到 grep 命令中。看起来应该很简单:

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

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

在这种情况下,我可能会通过使用 double greps 来解决这个问题,但我很好奇为什么这个单行代码会以这种方式运行。我很想听听关于在仍然使用这两个命令的同时修改它的方法的想法(因为这样做有速度优势)。

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

4

3 回答 3

9

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

此外,您不需要-ror ,它告诉它通过目录递归 - 但您正在测试单个文件。-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然后只打印文件名。

于 2012-07-19T16:52:03.903 回答
3

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

例如:

find . -wholename './cach*' -prune -o -exec grep "samson" "{}" +
于 2012-07-19T16:44:32.547 回答
3

您已经告诉grep自己递归(两次!-r并且-R是同义词)。由于您传递的参数之一是.(顶级目录),grep因此正在搜索每个文件(其中一些文件两次,或者如果它们在子目录中则更多)。

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

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。)

于 2012-07-19T17:01:13.683 回答