117

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

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

效果很好。问题是如何 grep 某个目录中的所有 html、htm、php 文件?

从this Use grep --exclude/--include syntax to not grep through certain files看来,我可以执行以下操作

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

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

4

7 回答 7

162

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

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

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

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

不要忘记你也可以使用findandxargs来做这种事情:

find /some/path/ -name "*.htm*" -or -name "*.php" | xargs grep "pattern"
于 2012-05-16T23:52:45.880 回答
41

using{html,php,htm}只能用作大括号扩展bash,这是、ksh和的非标准(不符合 POSIX)功能zsh

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

  • grep本身不理解符号{...}

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

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

大括号扩展的结果会受到通配(文件名扩展)的影响,这有以下缺陷

  • 如果每个结果参数碰巧包含不带引号的通配元字符,例如*.
    虽然这对于诸如此类的标记不太可能--include=*.html(例如,您必须有一个文件字面上命名为类似--include=foo.html的东西才能匹配),但总的来说值得牢记。

  • 如果nullglobshell 选项恰好打开 ( ) 并且通配符shopt -s nullglob匹配,则该参数将被丢弃

因此,对于完全稳健的解决方案,请使用以下内容:

grep -R '--include=*.'{html,php,htm} pattern /some/path
  • '--include=*.'由于被单引号引起来,被视为文字;这可以防止无意中将其解释为通配符。*

  • {html,php,htm}, - 必要的 - 不带引号的大括号扩展[1] ,扩展为3 个参数,由于{...} 直接跟在'...'token之后,因此包含该 token。

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

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

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

于 2017-05-22T19:56:03.207 回答
9

尝试删除双引号

grep --include=*.{html,php,htm} pattern -R /some/path
于 2012-05-16T13:10:07.020 回答
5

这不工作吗?

  grep pattern  /some/path/*.{html,php,htm} 
于 2012-05-16T13:08:03.733 回答
4

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

grep -v -E ".*\.(html|htm|php)"
于 2018-08-16T14:10:17.340 回答
2

尝试这个。-r 将进行递归搜索。-s 将抑制文件未找到错误。-n 将显示找到该模式的文件的行号。

    grep "pattern" <path> -r -s -n --include=*.{c,cpp,C,h}
于 2015-10-20T07:09:53.777 回答
0

grepfind命令一起使用

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

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

于 2012-05-16T16:22:23.293 回答