如何一次grep两个模式

时间:2015-06-06 14:25:03

标签: grep

我经常需要这样做命令行的事情,我管道grep并希望匹配两个不同的表达式。 (OR与A或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]+"   

当然这不起作用,但我想要等效的表达式。

3 个答案:

答案 0 :(得分:2)

在正则表达式中使用替换:

generate_out | grep -E '(foo|bar)[0-9]+'

使用-E启用ERE功能,这是一个。 (默认情况下,grep仅支持BRE; BRE的某些实现 - 例如GNU - 可能具有启用ER​​E功能的特殊语法;在GNU情况下,BRE中的\|相当于| in ERE;然而,依靠这些扩展而不是仅仅恰当地打开ERE是不可移植的。)

egrepgrep -E的向后兼容性同义词;但是,only the latter is specified as a requirement by POSIX

答案 1 :(得分:2)

使用awk简化:

generate_out| awk '/foo[0-9]+/ || /bar[0-9]+/'

当然可以在这种特殊情况下简化为:

generate_out| awk '/(foo|bar)[0-9]+/'

但一般情况下,您希望将awk用于简单,一致的ORAND的正则表达式:

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/)'

答案 2 :(得分:1)

使用grep的-e选项指定多个模式" OR':

$ seq 15 | grep -e 5 -e 3
3
5
13
15