如何从grep -R中排除目录?

TIM*_*MEX 599 unix linux grep

我想遍历所有子目录,但"node_modules"目录除外.

Joh*_*web 943

最新版本的GNU Grep(> = 2.5.2)提供:

--exclude-dir=dir
Run Code Online (Sandbox Code Playgroud)

它排除了dir与递归目录搜索中的模式匹配的目录.

所以你可以这样做:

grep -R --exclude-dir=node_modules 'some pattern' /path/to/search
Run Code Online (Sandbox Code Playgroud)

有关语法和用法的更多信息,请参阅

对于较旧的GNU Greps和POSIX Grep,请find按照其他答案中的建议使用.

或者只使用ack(编辑:或银色搜索者)并完成它!

  • 排除多个目录,如:`grep -r"Request".--exclude-DIR = {node_modules,GIT中,构建}` (64认同)
  • 不耐烦的语法:`--exclude-dir = dir`使用`grep`的正则表达式模式,_not_ shell的文件通配符.模式在相对于当前目录的路径上工作.所以使用模式`--exclude-dir = dir`,而不是`--exclude-dir ="/ root/dir/*"`. (26认同)
  • 如果你想从搜索中排除多个目录,是否有比使用更好的选择:`$ grep -r --exclude-dir = dir1 --exclude-dir = dir2"string"/ path/to/search/dir `? (14认同)
  • @Manocho:如果你认为'ack`很棒,试试The Silver Searcher并看看速度提升! (4认同)
  • 我可能花了太多时间在这个上比任何理智的人,但我不能为我的生活弄清楚如何从搜索中排除一个子目录 - "grep -r --exclude-dir = public keyword."的作品,但``grep -r --exclude-dir ='public/dist'关键字.`没有.我尝试添加正则表达式通配符,转义字符等,但似乎没有任何帮助. (3认同)
  • @Johnsyweb,我希望有一些东西,我不必多次提到`--exclude-dir`. (2认同)
  • @MatthewHerbst:您可以将 `grep` 包装在别名或脚本中。 (2认同)
  • @dkobozev 我也无法让它工作。必须使用以下解决方法:`grep -r keywords | grep -v '公共/分布'` (2认同)

hor*_*bzz 308

解决方案1(结合findgrep)

此解决方案的目的不是为了处理grep性能而是为了展示便携式解决方案:还应该使用busybox或早于2.5的GNU版本.

使用find,排除目录foo和bar:

find /dir \( -name foo -prune \) -o \( -name bar -prune \) -o -name "*.sh" -print
Run Code Online (Sandbox Code Playgroud)

然后结合find和非递归使用grep,作为便携式解决方案:

find /dir \( -name node_modules -prune \) -o -name "*.sh" -exec grep --color -Hn "your text to find" {} 2>/dev/null \;
Run Code Online (Sandbox Code Playgroud)

解决方案2(递归使用grep):

您已经知道这个解决方案,但我添加它,因为它是最新且最有效的解决方案.请注意,这是一种不太便携的解决方案,但更具人性化.

grep -R --exclude-dir=node_modules 'some pattern' /path/to/search
Run Code Online (Sandbox Code Playgroud)

要排除多个目录,请使用--exclude-diras:

--exclude-dir={node_modules,dir1,dir2,dir3}

解决方案3(Ag)

如果你经常搜索代码,Ag(The Silver Searcher)是一个比grep更快的替代品,它是为搜索代码而定制的.例如,它会自动忽略列出的文件和目录.gitignore,因此您不必继续将相同的繁琐排除选项传递给grepfind.

  • "这个组合"`find ... -exec`对我来说并不比`grep --exclude-dir`快.grep的巨大优势(使用26k +文件大约快5倍,在硬盘驱动器上过滤掉38k +),除非用find/exec组合替换`\;`和`+`.然后grep"仅"大约快30%.grep语法也是人类可读的:). (24认同)
  • 还注意到你可以用`--exclude-dir = {dir1,dir2}`排除多个 (8认同)
  • `node_modules` 是典型的例子,我一点也不惊讶。 (7认同)
  • 这个组合搜索速度比`--exclude-dir = dir`快,它显示颜色结果 - 易于阅读 (2认同)

Azo*_*ium 70

如果要排除多个目录:

"r"表示递归,"l"表示仅包含匹配的文件名和"i"表示忽略大小写区别:

grep -rli --exclude-dir={dir1,dir2,dir3} keyword /path/to/search
Run Code Online (Sandbox Code Playgroud)

示例:我想查找包含"hello"一词的文件.我想搜索 proc目录,启动目录,sys目录和目录之外的所有linux 目录:

grep -rli --exclude-dir={proc,boot,root,sys} hello /
Run Code Online (Sandbox Code Playgroud)

注意:上面的示例需要是root

注2(根据@skplunkerin):不要在逗号后添加空格 {dir1,dir2,dir3}

  • **注意:**不要在`{dir1,dir2,dir3}`中的逗号后添加空格 (4认同)
  • 您可以多次提供 `--exclude-dir` 选项。 (2认同)

Der*_*eit 42

这个语法

--exclude-dir={dir1,dir2}
Run Code Online (Sandbox Code Playgroud)

由shell(例如Bash)扩展,而不是grep由此扩展:

--exclude-dir=dir1 --exclude-dir=dir2
Run Code Online (Sandbox Code Playgroud)

引用将阻止shell扩展它,所以这不起作用:

--exclude-dir='{dir1,dir2}'    <-- this won't work
Run Code Online (Sandbox Code Playgroud)

使用的模式与选项--exclude-dir的手册页中描述的模式类型相同--exclude:

--exclude=GLOB
    Skip files whose base name matches GLOB (using wildcard matching).
    A file-name glob can use *, ?, and [...]  as wildcards, and \ to
    quote a wildcard or backslash character literally.
Run Code Online (Sandbox Code Playgroud)

shell通常会尝试自己扩展这样的模式,所以为了避免这种情况,你应该引用它:

--exclude-dir='dir?'
Run Code Online (Sandbox Code Playgroud)

您可以像这样使用花括号和引用排除模式:

--exclude-dir={'dir?','dir??'}
Run Code Online (Sandbox Code Playgroud)

模式可以跨越多个路径段:

--exclude-dir='some*/?lse'
Run Code Online (Sandbox Code Playgroud)

这将排除类似的目录topdir/something/else.


arc*_*don 13

经常使用这个:

grep可以与-r(递归),i(忽略大小写)和-o(仅打印匹配的部分行)一起使用.要排除files使用--exclude和排除目录使用--exclude-dir.

把它放在一起你会得到类似的东西:

grep -rio --exclude={filenames comma separated} \
--exclude-dir={directory names comma separated} <search term> <location>
Run Code Online (Sandbox Code Playgroud)

描述它使它听起来比实际复杂得多.用一个简单的例子更容易说明.

例:

假设我正在为debugger调试会话期间显式设置字符串值的所有地方搜索当前项目,现在希望查看/删除.

我编写了一个名为的脚本findDebugger.sh,用于grep查找所有出现的内容.然而:

对于文件排除 - 我希望确保.eslintrc被忽略(这实际上有一个关于debugger这样的lint规则应该被排除).同样,我不希望在任何结果中引用我自己的脚本.

对于目录排除 - 我希望排除,node_modules因为它包含许多引用的库,debugger我对这些结果不感兴趣.另外我只想省略.idea.git隐藏目录,因为我也不关心那些搜索位置,并希望保持搜索性能.

所以这是结果 - 我创建了一个调用的脚本findDebugger.sh:

#!/usr/bin/env bash
grep -rio --exclude={.eslintrc,findDebugger.sh} \
--exclude-dir={node_modules,.idea,.git} debugger .
Run Code Online (Sandbox Code Playgroud)


Dip*_*tch 10

你可以试试像 grep -R search . | grep -v '^node_modules/.*'

  • 在某些情况下,这不是一个好的解决方案 例如:如果'node_modules'目录是一个巨大的目录,有很多误报匹配(因此需要过滤掉目录),那么第一个grep浪费了大量时间搜索子目录,那么第二个grep过滤出局比赛.在第一个grep本身中排除node_modules会更快. (33认同)
  • 我不关心缓慢,我可以看看命令并知道它的作用 (2认同)
  • `--exclude-dir`是截至2016年的最佳解决方案. (2认同)

0xc*_*aff 9

如果您正在git存储库中查找代码,并且node_modules位于.gitignore,则可以使用git grepgit grep在工作树中搜索跟踪的文件,而忽略所有内容.gitignore

git grep "STUFF"
Run Code Online (Sandbox Code Playgroud)


Nag*_*gev 5

这里已经给出了许多正确的答案,但我添加这个是为了强调之前导致一些仓促尝试失败的一点:exclude-dir采用模式,而不是目录的路径。

假设您的搜索是:

grep -r myobject
Run Code Online (Sandbox Code Playgroud)

并且您注意到您的输出被src/other/objects-folder. 这个命令不会给你预期的结果:

grep -r myobject --exclude-dir=src/other/objects-folder
Run Code Online (Sandbox Code Playgroud)

你可能想知道为什么exclude-dir不工作!要实际从 中排除结果objects-folder,只需执行以下操作:

grep -r myobject --exclude-dir=objects-folder
Run Code Online (Sandbox Code Playgroud)

换句话说,只需使用文件夹名称,而不是路径。知道了就一目了然了。

从手册页:

--exclude-dir=GLOB
跳过名称后缀与模式 GLOB 匹配的任何命令行目录。递归搜索时,跳过基本名称与 GLOB 匹配的任何子目录。忽略 GLOB 中任何多余的尾部斜杠。

  • 在我在上面发布我的评论/问题之前,为什么我没有向下滚动到这个答案?不幸的是,我有一个坏习惯,就是忽略点赞数较少的答案,但这解释了我做错了什么,所以谢谢纳吉夫。 (3认同)
  • 我会发疯,因为我使用了子文件夹的完整路径,但它不起作用。在我看到这个评论后,我只使用了文件夹名称,它终于成功了!谢谢 (2认同)