当我想要grep某些目录中的所有html文件时,我会执行以下操作
grep --include="*.html" pattern -R /some/path
运作良好。问题是如何grep某些目录中的所有html,htm,php文件?
从Use grep --exclude/--include syntax to not grep through certain files开始,似乎我可以执行以下操作
grep --include="*.{html,php,htm}" pattern -R /some/path
但遗憾的是,这对我不起作用 仅供参考,我的grep版本是2.5.1。
答案 0 :(得分:108)
您可以使用多个--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"
HTH
答案 1 :(得分:21)
使用 {html,php,htm}
只能用作brace expansion ,这是bash
,ksh
的非标准(不符合POSIX标准)功能,和zsh
。
换句话说:不要尝试在针对/bin/sh
的脚本中使用它 - 在这种情况下使用显式多个--include
参数。
grep
本身不了解{...}
符号。
要识别大括号扩展,必须是命令行上未加引号(部分)令牌。
大括号扩展扩展为多个参数 ,因此在手边的情况grep
最终会看到多个 {{1选项,就像你已经单独传递它们一样。
大括号展开的结果受制于globbing(文件名扩展),其中有陷阱:
如果每个结果参数恰好包含未加引号通配符元字符,例如--include=...
,则可以进一步扩展为匹配文件名。
虽然*
之类的令牌不太可能发生这种情况(例如,你必须有一个文件字面上的名字类似--include=*.html
来匹配),它是值得记住的一般情况。
如果恰好打开--include=foo.html
shell选项(nullglob
)并且globbing匹配 nothing ,则参数将被丢弃
因此,对于完全可靠的解决方案,请使用以下命令:
shopt -s nullglob
grep -R '--include=*.'{html,php,htm} pattern /some/path
被视为文字;这可以防止无意中将'--include=*.'
解释为一个通配符。
*
, - 必要性 - 未加引号大括号扩展 [1]
,扩展为 3 参数,由于{html,php,htm}
直接跟在{...}
令牌之后,包含该令牌。
因此,在shell删除引号后,以下 3 文字参数最终会传递给'...'
:
grep
--include=*.html
--include=*.php
[1]更准确地说,它只是必须不加引号的大括号扩展的语法相关部分,列表元素可能仍然需要单独引用,并且必须是如果它们包含可能在支撑扩展后导致不需要的通配的全球元字符;虽然在这种情况下没有必要,但上述内容可以写成
--include=*.htm
答案 2 :(得分:9)
尝试删除双引号
grep --include=*.{html,php,htm} pattern -R /some/path
答案 3 :(得分:4)
这不起作用吗?
grep pattern /some/path/*.{html,php,htm}
答案 4 :(得分:2)
试试这个。 -r将进行递归搜索。 -s将抑制文件未找到错误。 -n将显示找到模式的文件的行号。
grep "pattern" <path> -r -s -n --include=*.{c,cpp,C,h}
答案 5 :(得分:0)
将grep
与find
命令
find /some/path -name '*.html' -o -name '*.htm' -o -name '*.php' -type f
-exec grep PATTERN {} \+
您也可以使用-regex
和-regextype
选项。
答案 6 :(得分:0)
它具有相同的用途,但没有--include
选项。它也适用于grep 2.5.1。
grep -v -E ".*\.(html|htm|php)"