Linux 将查找结果导入grep以快速排除目录

Linux 将查找结果导入grep以快速排除目录,linux,recursion,find,grep,piping,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引用,但这达到了预期效

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

find . -wholename './cach*' -prune -o -print
我现在希望将其导入grep命令。看起来应该很简单:

find . -wholename './cach*' -prune -o -print | xargs grep -r -R -i "samson"
。。。但这返回的结果大部分来自缓存目录。我已经尝试删除xargs引用,但这达到了预期效果,在文件名的文本上运行grep,而不是在文件本身上运行grep。我的目标是在任何不是缓存内容的文件中找到“samson”

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


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

使用find上的
-exec
选项,而不是将它们传输到另一个命令。从那里你可以使用
grep“samson”{}
在列出的每个文件中查找samson

例如:

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

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

另外,您的
grep
不需要
-r
-r
,它告诉它在目录中递归-但您正在测试单个文件

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

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


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

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

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

find . -path './cach*' -prune -o -print0 | xargs -0 grep -i "samson"
使用
-print0
-0
可以使脚本即使在包含空格或标点字符的文件名中也能工作

但是,您可能不需要在这里查找
find
,因为GNU grep能够排除目录:

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

(这也排除了
/deep/nested/directory/cache
。如果您只想排除顶层的缓存目录,请使用
find

谢谢!对我来说,消除递归就是解决这个问题的关键。(旧习惯很难改变。顺便说一句,这是我输入的错误,因为我通常使用“-r-I-I”,这比冗余递归标志更有意义。)“wholename”部分很好,因为不需要的子目录确实位于当前目录的根级别。现在是:
find-wholename./cach*.-prune-o-print | xargs grep-i-i“samson”
Awesome,很高兴它很简单=]如果当前文件夹/路径中有太多文件,单个
grep
将返回一个“太多参数”错误-因此您需要自己小心。感谢您捕获此错误!正如“已接受”的答案中所提到的,立即清理这些问题。你们太棒了。@newfurniture不,如果命令行太长(例如,如果我写了
grep…*
并且有很多文件),shell会出现“参数太多”错误。这里没有shell globbing,命令行正好是43个字符。
grep -R --exclude-dir='cach*' -i "samson" .