如何使用具有管道字元的模式 grep 多個模式?
我想在幾個文件中找到與兩種模式之一匹配的所有行。我試圖通過鍵入找到我正在尋找的模式
grep (foo|bar) *.txt
但是外殼將其解釋
|
為管道並在bar
不是執行檔時抱怨。如何在同一組文件中查找多個模式?
首先,您需要保護模式不被外殼擴展。最簡單的方法是在它周圍加上單引號。單引號防止它們之間的任何擴展(包括反斜杠);那麼你唯一不能做的就是在模式中使用單引號。
grep -- 'foo*' *.txt
(還要注意
--
選項結束標記,以阻止grep
包括 GNU 在內的某些實現grep
將名為-foo-.txt
例如的文件(將由 shell from 擴展*.txt
)作為選項(即使它遵循非選項參數)這裡))。如果確實需要單引號,則可以將其寫為
'\''
(結束字元串文字、文字引號、打開字元串文字)。grep -- 'foo*'\''bar' *.txt
其次,grep 至少支持兩種模式語法。舊的預設語法(基本正則表達式)不支持交替 (
|
) 運算符,儘管某些版本將其作為副檔名,但使用反斜杠編寫。grep -- 'foo\|bar' *.txt
可移植的方法是使用更新的語法,擴展正則表達式。您需要將
-E
選項傳遞給以grep
選擇它(以前是使用egrep
單獨的命令完成的²)grep -E -- 'foo|bar' *.txt
當您只是在尋找幾種模式中的任何一種(而不是使用析取建構複雜模式)時,另一種可能性是將多個模式傳遞給
grep
. 您可以通過在每個模式前面加上-e
選項來做到這一點。grep -e foo -e bar -- *.txt
或者將模式放在多行:
grep -- 'foo bar' *.txt
或者將這些模式儲存在一個文件中,每行一個並執行
grep -f that-file -- *.txt
請注意,如果
*.txt
擴展為單個文件,grep
則不會像存在多個文件時那樣在匹配的行前面加上其名稱。要解決這個問題,對於grep
GNU 等一些實現grep
,您可以使用該選項,或者對於任何實現,您可以作為額外參數-H
傳遞。/dev/null
¹ 一些
grep
實現甚至更支持與 perl 兼容的,帶有, 的-P
擴展*,*-X
用於-K
ksh 萬用字元…² 雖然
egrep
已被 POSIX 棄用並且有時在某些系統上不再存在,但在未安裝 POSIX 或 GNU 實用程序時,在某些其他系統(如 Solaris)上,這egrep
是您唯一的選擇,因為它不/bin/grep
支持-e
、-f
、或 multi-線條圖案-E``\|