2015-06-06 28 views
1

很多時候,我必須這樣做commandline的東西,我管道grep並希望匹配兩個不同的表達式。 (或OR A或B)如何一次grep兩個模式

例如,我想grep generate_out的輸出爲foo [0-9] +或bar [0-9] +。我當然可以只執行了兩次:

generate_out| grep "foo[0-9]+" 
generate_out| grep "bar[0-9]+" 

但往往generate_out是昂貴的,我寧願不希望兩次運行它(或存儲它的輸出)。相反,我想只使用一個表達式:

generate_out| grep "foo[0-9]+ OR bar[0-9]+" 

當然這不會工作,但我希望等效的表達式會。

回答

2

在您的正則表達式使用的交替:

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

採用-E使ERE特點,這是一個。 (默認情況下,grep只支持BRE; BRE的某些實現 - 比如GNU's - 可能有特殊的語法來啓用ERE功能;在GNU的情況下,BRE中的\|相當於ERE中的|;但是,依靠這樣的擴展,而不是隻是正確打開ERE)。


egrepgrep -E一個向後兼容同義詞;然而,only the latter is specified as a requirement by POSIX

+0

回答刪除,平行版兩個近似等於的答案:generate_out | egrep「foo [0-9] + | bar [0-9] +」。 –

2

爲簡單起見用AWK:

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

這當然可以在這種特殊情況下可以簡化爲:

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

但一般要使用AWK簡單,一致OR S和AND s的正則表達式:

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

這裏的OP的矯枉過正,但其他人發現這個問題可能需要這個更全面的答案(例如,爲了能夠在一行中需要多個匹配而不考慮它們的順序 - 當有隻有兩個價值觀,但超出這一點不合理),所以這是我的讚賞。 –

1

使用grep的-e選項指定多個「OR」的模式:

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