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

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

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

which works well. The problem is how to grep all the html,htm,php files in some directory?

从这个 Use grep --exclude/--include syntax to not grep through certain files,似乎我可以做到以下几点

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

但可惜的是,这对我不起作用。
仅供参考,我的 grep 版本是2.5。

78188 次浏览

is this not working?

  grep pattern  /some/path/*.{html,php,htm}

尝试删除双引号

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

使用 grepfind命令

find /some/path -name '*.html' -o -name '*.htm' -o -name '*.php' -type f
-exec grep PATTERN {} \+

您也可以使用 -regex-regextype选项。

你可以使用多个 --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"

试试这个。 R 会做一个递归搜索。 -s will suppress file not found errors. - n 将显示找到模式的文件的行号。

    grep "pattern" <path> -r -s -n --include=*.{c,cpp,C,h}

tl;dr

# Works in bash, ksh, and zsh.
grep -R '--include=*.'{html,php,htm} pattern /some/path

使用 {html,php,htm} can only work as a brace expansion,这是 bashkshzsh的非标准(不兼容 POSIX)特性。

  • 换句话说: 不要尝试在针对 /bin/sh的脚本中使用它——在这种情况下使用 露骨多个 --include参数。

  • grep itself does 没有 understand {...} notation.

对于要识别的大括号扩展,它在命令行上为 必须是 < em > 未引号 (a 的一部分)标记

一个大括号展开式 扩展到 < em > 多个参数 ,所以在手边的例子 ABC0最终会看到 < em > 多个 --include=...选项中,就好像你分别传递了它们一样。

花括号展开的结果是 受制于 globbing (文件名扩展),它有 陷阱:

  • Each resulting argument could further be expanded to matching filenames if it happens to contain 未被引用 globbing metacharacters such as *.
    虽然这种情况不太可能发生在 --include=*.html这样的标记上(例如,您必须有一个类似于 --include=foo.html的文件 字面意思就是才能与之匹配) ,但是一般情况下还是值得记住的。

  • 如果 nullglob shell 选项正好打开(shopt -s nullglob)并且 globbing 与 没什么匹配,则参数将为 被抛弃了

因此,对于 a fully robust solution,使用以下代码:

grep -R '--include=*.'{html,php,htm} pattern /some/path
  • '--include=*.' is treated as a 字面意思, due to being 单引号; this prevents inadvertent interpretation of * as a globbing character.

  • {html,php,htm},必要的-未被引用括号扩展 < sup > [1] ,展开为 3参数,由于 {...} 直接跟在 '...'令牌后面包括表示。

  • 因此,在引号被 shell 删除后,下面的 < em > 3 < em > 文字 参数最终传递给 grep:

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

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

它的作用是一样的,但是没有 --include选项。它也可以在 grep 2.5.1上使用。

grep -v -E ".*\.(html|htm|php)"