如何一次grep两种模式
How to grep two patterns at once
很多时候我不得不这样做命令行的事情,我通过管道连接到 grep 并希望匹配两个不同的表达式。 ( OR 匹配 A OR B。)
例如,我想为 foo[0-9]+ 或 bar[0-9]+ grep generate_out 的输出。我当然可以只执行两次:
generate_out| grep "foo[0-9]+"
generate_out| grep "bar[0-9]+"
但通常 generate_out 很昂贵,我不想 运行 它两次(或存储它的输出)。相反,我只想使用一个表达式:
generate_out| grep "foo[0-9]+ OR bar[0-9]+"
当然这行不通,但我想要等效的表达式。
在你的正则表达式中使用交替:
generate_out | grep -E '(foo|bar)[0-9]+'
-E
的使用启用了 ERE 功能,这是其中之一。 (默认情况下,grep 仅支持 BRE;BRE 的某些实现——例如 GNU 的——可能具有启用 ERE 功能的特殊语法;在 GNU 情况下,BRE 中的 \|
等同于 |
ERE;但是,依赖此类扩展而不是正确打开 ERE 是不可移植的。
egrep
是 grep -E
的向后兼容同义词;然而,only the latter is specified as a requirement by POSIX.
为简单起见,使用 awk:
generate_out| awk '/foo[0-9]+/ || /bar[0-9]+/'
在这种特殊情况下当然可以简化为:
generate_out| awk '/(foo|bar)[0-9]+/'
但一般来说,您希望将 awk 用于简单、一致的 OR
和 AND
正则表达式:
cmd | grep -E 'foo.*bar|bar.*foo'
cmd | awk '/foo/ && /bar/'
cmd | grep 'foo' | grep -v 'bar'
cmd | awk '/foo/ && !/bar/'
cmd | grep -E 'foo|bar'
cmd | awk '/foo/ || /bar/' (or awk '/foo|bar/')
cmd | grep -E 'foo|bar' | grep -E -v 'foo.*bar|bar.*foo'
cmd | awk '(/foo/ && !/bar/) || (/bar/ && !/foo/)'
使用 grep 的 -e
选项指定多个模式 "OR'ed":
$ seq 15 | grep -e 5 -e 3
3
5
13
15
很多时候我不得不这样做命令行的事情,我通过管道连接到 grep 并希望匹配两个不同的表达式。 ( OR 匹配 A OR B。)
例如,我想为 foo[0-9]+ 或 bar[0-9]+ grep generate_out 的输出。我当然可以只执行两次:
generate_out| grep "foo[0-9]+"
generate_out| grep "bar[0-9]+"
但通常 generate_out 很昂贵,我不想 运行 它两次(或存储它的输出)。相反,我只想使用一个表达式:
generate_out| grep "foo[0-9]+ OR bar[0-9]+"
当然这行不通,但我想要等效的表达式。
在你的正则表达式中使用交替:
generate_out | grep -E '(foo|bar)[0-9]+'
-E
的使用启用了 ERE 功能,这是其中之一。 (默认情况下,grep 仅支持 BRE;BRE 的某些实现——例如 GNU 的——可能具有启用 ERE 功能的特殊语法;在 GNU 情况下,BRE 中的 \|
等同于 |
ERE;但是,依赖此类扩展而不是正确打开 ERE 是不可移植的。
egrep
是 grep -E
的向后兼容同义词;然而,only the latter is specified as a requirement by POSIX.
为简单起见,使用 awk:
generate_out| awk '/foo[0-9]+/ || /bar[0-9]+/'
在这种特殊情况下当然可以简化为:
generate_out| awk '/(foo|bar)[0-9]+/'
但一般来说,您希望将 awk 用于简单、一致的 OR
和 AND
正则表达式:
cmd | grep -E 'foo.*bar|bar.*foo'
cmd | awk '/foo/ && /bar/'
cmd | grep 'foo' | grep -v 'bar'
cmd | awk '/foo/ && !/bar/'
cmd | grep -E 'foo|bar'
cmd | awk '/foo/ || /bar/' (or awk '/foo|bar/')
cmd | grep -E 'foo|bar' | grep -E -v 'foo.*bar|bar.*foo'
cmd | awk '(/foo/ && !/bar/) || (/bar/ && !/foo/)'
使用 grep 的 -e
选项指定多个模式 "OR'ed":
$ seq 15 | grep -e 5 -e 3
3
5
13
15