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

Shell 如何对多种文件类型使用grep--include选项?,shell,grep,Shell,Grep,当我想grep某个目录中的所有html文件时,我会执行以下操作 grep--include=“*.html”模式-R/some/path 这很有效。问题是如何grep某个目录中的所有html、htm、php文件 由此看来,我可以做到以下几点 grep--include=“*.{html,php,htm}”模式-R/some/path 但遗憾的是,这对我不起作用。 仅供参考,我的grep版本是2.5.1。这不起作用吗 grep pattern /some/path/*.{html,php,h

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

grep--include=“*.html”模式-R/some/path

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

由此看来,我可以做到以下几点

grep--include=“*.{html,php,htm}”模式-R/some/path

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

这不起作用吗

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

尝试删除双引号

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

使用
grep
find
命令

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}“模式”/some/path/

别忘了,您可以使用
find
xargs
来实现这类功能:

find/some/path/-name“*.htm*”-或-name“*.php”| xargs grep“模式”

试试这个。 -r将执行递归搜索。 -s将禁止出现“未找到文件”错误。 -n将显示找到模式的文件的行号

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

使用
{html,php,htm}
只能作为,这是
bash
ksh
zsh
的非标准(不符合POSIX)功能

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

  • grep
    本身不理解
    {…}
    符号。

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

大括号扩展扩展为多个参数,因此在本例中,
grep
最终会看到多个
--include=…
选项,就像您单独传递了它们一样

大括号扩展的结果会受到globbing(文件名扩展)
的影响,而globbing(文件名扩展)
存在缺陷:

  • 如果每个结果参数碰巧包含未加引号的全局元字符,例如
    *

    虽然像
    --include=*.html
    这样的标记不太可能出现这种情况(例如,您必须有一个名为
    --include=foo.html
    的文件才能进行匹配),但一般来说值得记住

  • 如果恰好打开了
    nullglob
    shell选项(
    shopt-s nullglob
    ),并且globbing与任何内容都不匹配,则该参数将被丢弃

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

grep -R '--include=*.'{html,php,htm} pattern /some/path
  • ”--include=*。
    由于是单引号,因此被视为文字;这可以防止无意中将
    *
    解释为全局字符

  • {html,php,htm}
    ,必要的无引号大括号扩展[1] ,扩展为3个参数,由于
    {…}
    紧跟在
    '.'
    标记之后,这些参数包括该标记

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

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

[1] 更准确地说,只有大括号扩展中与语法相关的部分必须是不带引号的,列表元素仍然可以单独带引号,如果它们包含可能导致大括号扩展后不需要的全局元字符,则必须是;虽然在这种情况下没有必要,但上述内容可以写成

'--include=*.{'html'、'php'、'htm'}
它的作用相同,但没有
--include
选项。它也适用于grep2.5.1

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

不是真的。这些文件可能位于子目录的子目录中,我看到了问题所在。我使用--include=“.html,php}”来阻止shell扩展“”,同时阻止shell扩展{html,php}。似乎等号in--include=*能够阻止shell扩展'*';很多时候,当您需要此功能时,您所处理的文件比xargs所能处理的要多。@JamesMoore:看一看。它通常可以用作
xargs
的替代品。也值得一读。HTH.@tianyapiaozi:你是对的,围绕支架展开的引用是问题所在;但是,如果没有引用,
*
作为它所嵌入的令牌的一部分仍然要进行全局绑定,在这种情况下,它恰好与任何内容都不匹配,因为只有字面上命名为类似
--include=foo.html
的文件才会匹配。为了安全起见,请引用
*
(您可以使用
\*
单独执行此操作)。作为一个额外的好处,这在视觉上更清楚地表明,在这种情况下,不是shell应该执行全局绑定。至于
查找
解决方案:使用
-exec grep“pattern”{}+
而不是
;xargs grep“pattern”
更健壮(例如,处理带有空格的文件名)而且效率更高。@tianyapiaozi Try
grep--include=\*.{html,php,htm}模式-R/some/path
。这对我来说很有效。这对我来说是最好的答案,我想你可以用-rsn而不是-r-s-n(但这是吹毛求疵)。通常我用-rns。为了清楚起见,在这个例子中我不得不提到-r-n-s:-)很高兴它有帮助。