【问题标题】:How can I exclude directories from grep -R?如何从 grep -R 中排除目录?
【发布时间】:2011-09-27 18:31:50
【问题描述】:

我要遍历所有子目录,除了“node_modules”目录。

【问题讨论】:

  • 如果您在 git 存储库中查找代码并且 node_modules 在您的 .gitignore 中,git grep "STUFF" 是最简单的方法。 git grep 在工作树中搜索跟踪的文件,忽略 .gitignore 中的所有内容
  • 节点示例:grep -R --exclude-dir={node_modules,bower_components} "MyString" | cut -c1-"$COLUMNS" - 此外,您始终可以在 shell 中将其别名为 'nodegrep' 或其他任何内容,并使用命令参数作为字符串输入..

标签: linux unix grep


【解决方案1】:

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

--exclude-dir=dir

从递归目录搜索中排除与模式 dir 匹配的目录。

所以你可以这样做:

grep -R --exclude-dir=node_modules 'some pattern' /path/to/search

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

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

或者只使用ack编辑:或The Silver Searcher)就可以了!

【讨论】:

  • @Manocho:如果您认为ack 很棒,请尝试使用 The Silver Searcher 并查看速度提升!
  • 不耐烦的语法:--exclude-dir=dir 使用grep 的正则表达式模式,不是 shell 的文件通配。模式适用于相对于当前目录的路径。所以使用模式--exclude-dir=dir,而不是--exclude-dir="/root/dir/*"
  • 如果您希望从搜索中排除多个目录,还有比使用:$ grep -r --exclude-dir=dir1 --exclude-dir=dir2 "string" /path/to/search/dir 更好的选择吗?
  • 我可能比任何理智的人都花太多时间在这上面,但我终生无法弄清楚如何从搜索中排除子目录 - grep -r --exclude-dir=public keyword . 有效,但 @ 987654340@ 没有。我尝试添加正则表达式通配符、转义字符等,但似乎没有任何帮助。
  • 像这样排除多个目录:grep -r "Request" . --exclude-dir={node_modules,git,build}
【解决方案2】:

解决方案 1(结合 findgrep

此解决方案的目的不是处理grep 的性能,而是展示一个可移植的解决方案:也应该适用于busybox 或早于2.5 的GNU 版本。

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

find /dir \( -name foo -prune \) -o \( -name bar -prune \) -o -name "*.sh" -print

然后结合 findgrep 的非递归使用,作为一个可移植的解决方案:

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

解决方案 2(使用 grep--exclude-dir 选项):

您已经知道此解决方案,但我添加它是因为它是最新且最有效的解决方案。请注意,这是一个不太便携的解决方案,但更易于阅读。

grep -R --exclude-dir=node_modules 'some pattern' /path/to/search

要排除多个目录,请将--exclude-dir 用作:

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

解决方案 3(银)

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

【讨论】:

  • 这个组合的搜索速度比--exclude-dir=dir 快,而且它用颜色显示结果 - 易于阅读
  • “这个组合”find ... -exec 对我来说并不比grep --exclude-dir 快。 grep 的巨大优势(对于 26k+ 文件,大约快五倍,在 HDD 上过滤掉 38k+ 文件),除非您将 \; 替换为 + 用于 find/exec 组合。然后 grep “只”快 30% 左右。 grep 语法也是人类可读的:)。
  • 同意,因为这是显而易见的。一些busyboxes没有GREP命令。
  • 还注意到您可以使用--exclude-dir={dir1,dir2}排除多个
  • node_modules 是典型的例子我一点也不惊讶。
【解决方案3】:

如果要排除多个目录

“r”表示递归,“l”只打印包含匹配项的文件名,“i”表示忽略大小写区别:

grep -rli --exclude-dir={dir1,dir2,dir3} keyword /path/to/search

示例:我想查找包含单词“hello”的文件。我想在我所有的 linux 目录中搜索 except proc 目录、boot 目录、sys 目录和 目录:

grep -rli --exclude-dir={proc,boot,root,sys} hello /

注意:上面的例子需要root权限

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

【讨论】:

  • 注意:不要在{dir1,dir2,dir3}中的逗号后添加空格
  • 谢谢,在通过 SVN 工作区 grep 时很方便:grep -Irsn --exclude-dir=.svn 'foo' .
  • 您可以多次提供--exclude-dir 选项。
【解决方案4】:

这个语法

--exclude-dir={dir1,dir2}

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

--exclude-dir=dir1 --exclude-dir=dir2

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

--exclude-dir='{dir1,dir2}'    <-- this won't work

--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.

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

--exclude-dir='dir?'

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

--exclude-dir={'dir?','dir??'}

【讨论】:

    【解决方案5】:

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

    git grep "STUFF"
    

    【讨论】:

    • 这是非常有用的提示。谢谢。
    【解决方案6】:

    经常使用这个:

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

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

    grep -rio --exclude={filenames comma separated} \
    --exclude-dir={directory names comma separated} <search term> <location>
    

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

    示例:

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

    我编写了一个名为findDebugger.sh 的脚本并使用grep 来查找所有出现的事件。然而:

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

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

    结果如下 - 我创建了一个名为 findDebugger.sh 的脚本:

    #!/usr/bin/env bash
    grep -rio --exclude={.eslintrc,findDebugger.sh} \
    --exclude-dir={node_modules,.idea,.git} debugger .
    

    【讨论】:

    • 我认为“r”选项应该打印大写“-R”。
    • 有趣。 "r" 在 nix 和 mac 上一直对我有用。
    • 当我写my answer时,我使用了-R(我现在不记得为什么了)。我通常使用-r。原来是大写版本follows symlinks。直到。
    • @Johnsyweb - 谢谢。赞成你的答案 - 不记得什么时候,可能是在 2016 年我添加这个的时候:)
    【解决方案7】:

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

    【讨论】:

    • 在某些情况下不是一个很好的解决方案。例如:如果“node_modules”目录很大,有很多误报匹配(因此需要过滤掉该目录),那么第一个 grep 会浪费大量时间搜索子目录,然后第二个 grep 过滤出比赛。在第一个 grep 本身中排除 node_modules 会更快。
    • 我不关心慢,看命令就知道它做了什么
    • Guru 的评论同上。在我的情况下,/var 的 grep 在遇到 /var/run 时会挂起。因此,我首先要避免使用该目录的原因。
    • --exclude-dir 是截至 2016 年的最佳解决方案。
    【解决方案8】:

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

    假设您的搜索是:

    grep -r myobject
    

    您注意到您的输出中充满了来自src/other/objects-folder 的结果。这个命令不会给你预期的结果:

    grep -r myobject --exclude-dir=src/other/objects-folder
    

    您可能想知道为什么exclude-dir 不起作用!要真正从objects-folder 中排除结果,只需执行以下操作:

    grep -r myobject --exclude-dir=objects-folder
    

    换句话说,只使用文件夹名称,而不是路径。一旦你知道它就很明显了。

    来自手册页:

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

    【讨论】:

    • 为什么在我在上面发布我的评论/问题之前我没有向下滚动到这个答案?不幸的是,我有一个坏习惯,即忽略支持较少的答案,但这解释了我做错了什么,所以感谢 Nagev。
    【解决方案9】:

    非常有用,特别是对于那些处理Node.js 的人,我们希望避免在“node_modules”中搜索:

    find ./ -not -path "*/node_modules/*" -name "*.js" | xargs grep keyword
    

    【讨论】:

      【解决方案10】:

      一个简单的工作命令:

      root/dspace# grep -r --exclude-dir={log,assetstore} "creativecommons.org"
      

      上面我在当前目录“dspace”中查找文本“creativecommons.org”并排除目录 {log,assetstore}。

      完成。

      【讨论】:

      • 整洁,包括括号中的几个目录
      【解决方案11】:

      这个对我有用:

      grep <stuff> -R --exclude-dir=<your_dir>
      

      【讨论】:

      • 这个答案与已经发布的有什么不同?
      【解决方案12】:
      find . ! -name "node_modules" -type d 
      

      【讨论】:

        【解决方案13】:

        第 1 步:

        vim ~/.bash_profile

        search() {
            grep -InH -r --exclude-dir=*build*  -e "$1" .
        }
        

        第 2 步:

        source ~/.bash_profile

        用法:

        search "&lt;string_to_be_searched&gt;"

        【讨论】:

          【解决方案14】:

          更简单的方法是使用“grep -v”过滤结果。

          grep -i needle -R * | grep -v node_modules

          【讨论】:

          • 这实际上与 DipSwitch 3 年前提供的答案相同。它也有同样的问题。
          猜你喜欢
          • 2010-12-02
          • 2015-03-20
          • 1970-01-01
          • 2021-01-09
          • 2012-05-12
          • 1970-01-01
          • 1970-01-01
          • 2016-12-25
          • 2021-11-22
          相关资源
          最近更新 更多