递归grep:排除特定目录


49

我经常使用递归grep查找具有特定内容的源文件。

grep -Rni "myfunc" .

在大型代码库上,这可能会变慢,因此我使用--incldue来限制/白名单扩展。

grep -Rni --include=*.java "myfunc" .

但是,我在想排除(修剪)整个子目录会更有效:

grep -Rni --exclude=/.svn/ "myfunc" .

但是--exclude仅支持上述* .java这样的文件模式。如何排除目录?

Answers:


10

您可能会调查ack

我刚刚开始使用它,但它似乎非常适合。


ack看起来还不错。很好,它可以直观地排除不需要的文件。--nogroup选项提供的输出类似于grep -Rni
gabor

2
Ack有点慢。您可以尝试使用Silver Searcher(Ag)或ripgrep(rg)。
user31389

62
grep -r --exclude-dir=dev --exclude-dir=sys --exclude-dir=proc PATTERN data

资料来源:https : //stackoverflow.com/questions/2799246/grep-clusion-a-specific-folder-using


17
请注意,这是递归排除的。./dev将与一起排除在外./foo/bar/dev。使用--exclude-dir=./dev只适用于第一种情况。
科里·沃克

4
您还可以通过globing来稍微缩短一点:globing bash grep -r --exclude-dir={dev,sys,proc} PATTERN data 的唯一问题是我无法使其在bash中正常工作。在这种情况下,我必须将它们分开。
2014年

3
另请注意,{}仅在您输入多个条目时有效,这意味着--exclude-dir = {home,.svn}是有效的,但--exclude-dir = {。svn}则无效。浪费我的时间弄清楚{}为什么不起作用,因为我首先测试了1个条目。
林果皞

如果您使用{}单个条目,则可能需要一个一元逗号来使其成为数组(不确定Bash如何处理它)。而不是这样做,我最终在.bash_aliases中创建了一个别名,该别名遍历我通常一直想排除的文件夹列表,例如.git,.svn,.hg,.cache,然后通过带有--exclude-dir $dir然后将该数组扩展为grep别名。
Dragon788

6

您可以改用find:

find . -not -path "*/.svn*" -not -type d -exec grep -ni "myfunc" {} \; -print

好的,这有点倒退,您首先得到grep结果,然后是路径。也许其他人有更好的答案?


3
好的,我非常喜欢。当然,查找要灵活得多。输出之间的唯一区别是,“ grep -Rni”将为每个匹配项打印文件名,而“ find -exec grep”将在一行中打印文件名,然后在每次匹配项中打印一行(带有行号和行内容) )。使用“ grep -Hni”强制文件名显示在每行上
gabor

感谢您提供的唯一答案,对于没有grep --exclude-dir却很棘手的系统有效,但仍必须使用
Dmitri DB

2

这是我的一个项目中脚本的一个完整示例,可能会有所帮助,我将此文件称为“ all_source”(标记为可执行文件),并将其放在项目的根目录中,然后像grep myfunc $(./all_source)脚本末尾的sort 一样完全调用它可选的。

#!/bin/bash

find . \
    -type d \( \
            -wholename './lib' -o \
            -wholename './vc6' -o \
            -name 'gen' -o \
            -name '.svn' \
            \) -prune -o \
    -type f \( \
            -name '*.h' -o \
            -name '*.cpp' -o \
            -name '*.c' -o \
            -name '*.lua' -o \
            -name '*.*awk' \) -print \
    | sort

此脚本返回所有的文件名的项目,该项目的比赛*.h, *.cpp, *.c, *.lua, *.*awk,但在一个名为.svn的所有文件夹和文件夹的根不搜索,以及跳过的文件夹./lib./vc6(但只有那些马上项目的根目录)。因此,当您执行grep myfunc $(./all_source)此操作时,仅会进入那些文件。您还需要从项目的根目录中调用它。


0

还有-prune选项可以找到:

 find . -path "*/.svn*" -prune -o -not -type d -exec grep -ni "myfunc" {} \; -print

0

您可以尝试这样做:

grep -R  "myfunc" . | grep -v path_to_exclude/

例如:如果您不想搜索日志文件中的内容,请执行以下操作:

grep -R "myfunc" . | grep -v log/
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.