如何在bash中使用复杂的正则表达式?
我正在尝试grep文件backend.conf
:
cat backend.conf | grep "server (?:[0-9]{1,3}\.){3}[0-9]{1,3}"
但我没有看到任何匹配,即使backend.conf
的内容有:
server 172.31.21.45 max_fails=3 fail_timeout=30s;
哪个应该匹配。
答案 0 :(得分:2)
标准grep使用不了解范围的正则表达式引擎,并且需要转义特殊字符。扩展正则表达式将正确处理这些原子和运算符,因此请使用egrep
,grep -E
或pcregrep
,具体取决于特定系统上的可用内容。
$ echo 'server 172.31.21.45 max_fails=3 fail_timeout=30s;' |
egrep 'server (?:[0-9]{1,3}\.){3}[0-9]{1,3}'
server 172.31.21.45 max_fails=3 fail_timeout=30s;
请注意,GNU grep(至少通过v2.20)不支持您正在使用的某些原子。特别是,如果没有Perl兼容的正则表达式(PCRE)库,则不支持具有?:
的非捕获组,许多Linux发行版默认情况下不会编译为GNU grep。
要查看您是否获得PCRE支持,请尝试ldd $(which grep) | fgrep -i pcre
查看PCRE库是否已关联。如果是,您可能只需添加-P
或--perl-regexp
标记为表达式启用它。
如果不已编译PCRE,则捕获该组:
$ echo 'server 172.31.21.45 max_fails=3 fail_timeout=30s;' |
egrep 'server ([0-9]{1,3}\.){3}[0-9]{1,3}'
server 172.31.21.45 max_fails=3 fail_timeout=30s;
或安装并使用pcregrep
代替:
$ echo 'server 172.31.21.45 max_fails=3 fail_timeout=30s;' |
pcregrep 'server (?:[0-9]{1,3}\.){3}[0-9]{1,3}'
server 172.31.21.45 max_fails=3 fail_timeout=30s;
当然 支持非捕获组。
答案 1 :(得分:0)
默认情况下,grep使用BRE(基本正则表达式)语法,它提供:
grep 'server \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}'
如果你想要更轻的东西,你可以使用ERE(扩展正则表达式)语法:
grep -E 'server ([0-9]{1,3}\.){3}[0-9]{1,3}'
请注意,这些语法都不知道什么是非捕获组。
答案 2 :(得分:0)
对我而言:
echo 'server 172.31.21.45 max_fails=3 fail_timeout=30s;' | grep -E "server ([0-9]{1,3}\.){3}[0-9]{1,3}"
(请注意简短(
而不是其他答案中的(?:
和您的问题。)
答案 3 :(得分:0)
我可以工作。我检查了grep(GNU grep)2.20
$ echo 'server 172.31.21.45 max_fails=3 fail_timeout=30s;' | grep -E "server ([0-9]{1,3}\.){3}[0-9]"
(命令与其他答案相同)
注意:
如果使用grep
的-o选项,则可以轻松确认正则表达式。 grep -o PATTERN
仅输出与PATTERN匹配的字符串
示例:
$ echo 'server 172.31.21.45 max_fails=3 fail_timeout=30s;' | grep -o -E "server [0-9]{1,3}"
server 172
$ echo 'server 172.31.21.45 max_fails=3 fail_timeout=30s;' | grep -o -E "server ([0-9]{1,3})"
server 172
$ echo 'server 172.31.21.45 max_fails=3 fail_timeout=30s;' | grep -o -E "server (?:[0-9]{1,3})"
$