grep:使用方括號匹配特定字元
所以我正在使用這些資源來試驗 grep 的力量
我目前遇到的問題是它似乎沒有按我的預期工作。所以我有一個包含foo.txt的 demo.txt 文件,我使用此程式碼搜尋它:
grep [a-z][a-z]o.txt demo.txt
但它返回空。zsh: no matches found: [a-z][a-z]o.txt
請問是不是我對方括號的使用理解有誤?這是圖片:
因為您沒有引用要傳遞給的正則表達式
grep
,所以它被 shell 擷取,並且 shell在呼叫之前grep
嘗試擴展它。現在,您使用的正則表達式恰好也是一個有效的 shell glob 模式1,這意味著“列出目前文件夾中名稱為任意兩個字元的所有文件或目錄,後跟字元串o.txt
”。如果您的目前目錄包含與該 glob 匹配的任何文件或子目錄,則 glob 將擴展為匹配的文件名:$ ls abo.txt demo.txt $ cat demo.txt foo.txt $ set -x $ grep [a-z][a-z]o.txt demo.txt +zsh:7> grep abo.txt demo.txt
set -x
告訴顯示它執行的zsh
實際命令。如您所見,[a-z][a-z]o.txt
擴展為匹配的文件名:abo.txt
,這就是傳遞給grep
.現在,您的目錄中實際上沒有任何匹配的文件名,這意味著
zsh
將模式擴展為空字元串,甚至根本沒有啟動grep
。這就是錯誤的原因zsh: no matches found: [a-z][a-z]o.txt
。那是 zsh 告訴您它無法將 glob 擴展到任何匹配的文件。最後,如果您正確引用該模式,會發生這種情況:
$ grep '[a-z][a-z]o.txt' demo.txt +zsh:12> grep '[a-z][a-z]o.txt' demo.txt foo.txt
這一次,引號保護了模式免受 shell 的影響,shell 將其按原樣傳遞給
grep
並grep
反過來將其解釋為正則表達式,意思是“任何兩個小寫字母,然後是一個o
,然後是任何其他字元,並以txt
”結尾。這是一個重要的細節,因為.
在正則表達式中表示“任何字元”。所以你真正想要的是:grep '[a-z][a-z]o\.txt' demo.txt
“
\.
轉義” the.
使其僅匹配文字點,不再表示“任何字元”。所以,總是引用你的正則表達式並小心.
!最後,這是使用擴展正則表達式編寫此程式碼的另一種方法:
$ grep -E '[a-z]{2}o\.txt' demo.txt foo.txt
1請參閱正則表達式的定義是什麼?有關 glob 與正則表達式的更多詳細資訊。