Shell

grep:使用方括號匹配特定字元

  • January 22, 2021

所以我正在使用這些資源來試驗 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 將其按原樣傳遞給grepgrep反過來將其解釋為正則表達式,意思是“任何兩個小寫字母,然後是一個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 與正則表達式的更多詳細資訊。

引用自:https://unix.stackexchange.com/questions/630399