2012-07-19 62 views
10

我成功使用find来创建当前子目录中的所有文件的列表,不包括子目录“缓存”中的所有文件。这是我的第一位代码:管道找到grep进行快速目录排除的结果

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

我现在希望将其管理为grep命令。它似乎应该很简单:

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

...但这是返回的结果,主要是从缓存目录。我试过删除xargs引用,但是这样做的确如你所期望的那样,在文件名的文本上运行grep,而不是在文件本身上运行。我的目标是在任何没有缓存内容的文件中找到“samson”。

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

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

回答

9

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

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

您可以使用管道版本,或单命令来更新你的命令:

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将只打印文件名。

+0

谢谢!递归的去除对我来说是个诀窍。 (旧习惯很难死掉,顺便说一句,这是我的一个错误类型,因为我通常使用“-r -i -I”,这比冗余递归标志更有意义)。“全名”部分很好,因为不需要的子目录确实在当前目录的根目录中。所以现在是: 'find。 -wholename'./cach*'-prune -o -print | xargs grep -i -I“samson”' – eternalnewb 2012-07-19 17:01:51

+0

太棒了,很高兴这很简单=] – newfurniturey 2012-07-19 17:04:26

3

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

例如:

find . -wholename './cach*' -prune -o -exec grep "samson" "{}" + 
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

+0

如果当前文件夹/路径中的文件太多,单个'grep'将返回一个“太多参数”的错误 - 所以你需要注意这一点。 – newfurniturey 2012-07-19 17:03:16

+0

感谢您的支持!正如在“接受”答案中提到的那样,立即清理那些固定的东西。你们很棒。 – eternalnewb 2012-07-19 17:04:54

+0

@newfurniturey不,如果命令行太长(例如,如果我写了'grep ... *'并且有很多文件),那么shell会出现“太多参数”错误。这里没有shell匹配,命令行恰好是43个字符。 – Gilles 2012-07-19 17:12:58