如何为多种文件类型使用grep --include选项?

tia*_*ozi 88 shell grep

当我想要grep某些目录中的所有html文件时,我会执行以下操作

grep --include="*.html" pattern -R /some/path

效果很好.问题是如何grep某些目录中的所有html,htm,php文件?

从这个使用grep --exclude/ - include语法不grep通过某些文件,似乎我可以做到以下几点

grep --include="*.{html,php,htm}" pattern -R /some/path

但遗憾的是,这对我不起作用.
仅供参考,我的grep版本是2.5.1.

Ste*_*eve 122

您可以使用多个--include标志.这对我有用:

grep -r --include=*.html --include=*.php --include=*.htm "pattern" /some/path/

但是,您可以按照Deruijter建议执行操作.这对我有用:

grep -r --include=*.{html,php,htm} "pattern" /some/path/

不要忘记你可以使用findxargs为这类事情:

find /some/path/ -name "*.htm*" -or -name "*.php" | xargs grep "pattern"

HTH

  • @tianyapiaozi:你是正确的,围绕支撑扩展的引用是问题; 但是,如果没有引用,`*`仍然受到globbing _as的影响,它是嵌入in_的一部分,它只是_happens_在这种情况下不匹配任何东西,因为只有文件_literally_命名为`--include = foo.html `会匹配.为了安全起见,引用`*`(你可以用`\*`单独做).作为一个额外的奖励,这使得它_visually_更​​清楚,不是应该在这种情况下执行globbing的shell_. (3认同)
  • 我看到了问题。我使用 --include="*.{html,php}" 来防止 shell 扩展 '*',同时阻止 shell 扩展 {html,php}。似乎 --include=* 中的等号能够阻止 shell 扩展“*”。 (2认同)
  • @JamesMoore:看看[GNU Parallel](https://www.gnu.org/software/parallel/).它通常可以用作`xargs`的替代品.[This](https://www.gnu.org/software/parallel/man.html#differences_between_xargs_and_gnu_parallel)也值得快速阅读.HTH. (2认同)
  • 至于`find`解决方案:使用`-exec grep"模式"{} +`而不是`| xargs grep"pattern"`更健壮(例如,处理带空格的文件名)以及更高效. (2认同)

mkl*_*nt0 26

使用{html,php,htm}只能作为工作括号扩展,这是一个非标准的(不是POSIX兼容)功能bash,kshzsh.

  • 换句话说:不要尝试在目标脚本中使用它/bin/sh- 在这种情况下使用显式多个--include参数.

  • grep本身并没有明白{...}的符号.

要识别大括号扩展,它必须是命令行上的未加引号(部分)令牌.

大括号扩展扩展为多个参数,因此在手头的情况下grep最终会看到多个 --include=...选项,就像您已经单独传递它们一样.

大括号扩展的结果受到globbing(文件名扩展)的影响,这有一些陷阱:

  • 如果碰巧包含不带引号的 globbing元字符,如每个结果参数可以进一步扩展为匹配文件名*.
    虽然这是不太可能有令牌,如--include=*.html(例如,你必须有一个文件字面上命名类似--include=foo.html的东西来匹配),这是值得铭记一般.

  • 如果nullglobshell选项发生在(被打开shopt -s nullglob)和通配符匹配什么,参数会被丢弃.

因此,要获得完全可靠的解决方案,请使用以下命令:

grep -R '--include=*.'{html,php,htm} pattern /some/path
Run Code Online (Sandbox Code Playgroud)
  • '--include=*.'单引号而被视为文字 ; 这可以防止无意中将其解释为通配符.*

  • {html,php,htm}, - 必要性 - 不带引号的大括号扩展[1] ,扩展为3个参数,由于{...} 直接跟随'...'令牌,它包含该令牌.

  • 因此,在shell删除引号后,以下3个 文字参数最终传递给grep:

    • --include=*.html
    • --include=*.php
    • --include=*.htm

[1]更准确地说,只有大括号扩展的语法相关部分必须不加引号,列表元素可能仍然是单独引用的,并且必须是如果它们包含可能在大括号扩展后导致不需要的通配的通配元字符; 虽然在这种情况下没有必要,但上述内容可以写成
'--include=*.'{'html','php','htm'}


Der*_*ter 9

尝试删除双引号

grep --include=*.{html,php,htm} pattern -R /some/path
Run Code Online (Sandbox Code Playgroud)

  • @tianyapiaozi 尝试 `grep --include=\*.{html,php,htm} 模式 -R /some/path`。这对我有用。 (3认同)

Vij*_*jay 5

这不工作吗?

  grep pattern  /some/path/*.{html,php,htm} 
Run Code Online (Sandbox Code Playgroud)


Koh*_*ami 5

它的作用相同,但没有--include选择。它也适用于 grep 2.5.1。

grep -v -E ".*\.(html|htm|php)"
Run Code Online (Sandbox Code Playgroud)