如何在grep命令中使用--include选项来匹配多种文件类型?
如何在grep命令中使用--include选项来匹配多种文件类型?
当我想要在某个目录中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。
tl;dr
# Works in bash, ksh, and zsh. grep -R '--include=*.'{html,php,htm} pattern /some/path
使用{html,php,htm}
只能作为一种非标准(不符合POSIX标准)的绝括号扩展,在bash
、ksh
和zsh
中有效。
-
换句话说:不要在针对
/bin/sh
的脚本中尝试使用它-在这种情况下使用明确的多个--include
参数。 -
grep
本身不理解{...}
符号。
要识别大括号扩展,它必须是命令行上未引用的(一部分)标记。
大括号扩展扩展为多个参数,因此在这种情况下,grep
最终看到多个--include=...
选项,就像您单独传递它们一样。
大括号扩展的结果受到通配符(文件名扩展)的影响,存在陷阱:
-
如果每个结果的参数进一步扩展为匹配的文件名(例如,它碰巧包含未引用的通配符元字符,例如
*
)。
虽然使用--include=*.html
之类的令牌不太可能(例如,您必须拥有一个实际命名为--include=foo.html
的文件才能匹配某些内容),但总的来说,请记住这一点。 -
如果
nullglob
shell选项恰好被打开(shopt -s nullglob
),并且通配符无法匹配任何内容,则该参数将被舍弃。
因此,对于完全强大的解决方案,请使用以下内容:
grep -R '--include=*.'{html,php,htm} pattern /some/path
-
'--include=*.'
被视为字面值,因为它被单引号包含;这可以防止错误解释*
为通配符字符。 -
{html,php,htm}
-必须是未引用的大括号扩展[1],扩展为3个参数,由于{...}
直接跟在'...'
标记后面,因此这些参数包括该标记。 -
因此,在壳体去除引号之后,最终传递给
grep
的是以下3个文本参数:--include=*.html
--include=*.php
--include=*.htm
[1] 更准确地说,只有大括号扩展的语法相关部分必须未引用,列表元素可能仍然是独立引用的,如果它们包含可能导致大括号扩展后产生不需要的通配符扩展的通配符元字符;虽然在这种情况下不必要,但上述内容可以写成
'--include=*.'{'html','php','htm'}
你可以使用多个--include
标志。这适用于我:
grep -r --include=*.html --include=*.php --include=*.htm "pattern" /some/path/
但是,你可以按照Deruijter提出的建议来做。这适用于我:
grep -r --include=*.{html,php,htm} "pattern" /some/path/
不要忘记你也可以使用find
和xargs
进行这种操作:
find /some/path/ -name "*.htm*" -or -name "*.php" | xargs grep "pattern"