The grep 指令是一個強大的公用程式,用於在文字中搜尋模式。它預先安裝在任何 Linux 發行版中。這是我們的 關於設定 LAMP Stack - Linux、Apache、MySQL 和 PHP 的教學課程.
grep 這個名稱代表全域正規表示式列印(global regular expression print)。該工具在輸入中搜尋指定的模式。原則上,這聽起來微不足道。然而,它真正的強大之處在於您如何定義模式。本指南 詳細說明了如何將 grep 與正規表示式結合使用以進行複雜的搜尋。 讓我們開始吧!
如何使用 Grep
grep 指令本身並不複雜。它只需要模式和要在其中進行搜尋的內容。以下是 grep 指令的基本結構:
|
1 |
grep <regex> <file> |
搜尋文字
首先,取得一個範例檔案來執行操作。下載 GNU General Public License v3.0(文字格式)。這是一個相當大的文字檔案,包含許多單字和片語。如果您使用的是 Ubuntu,您可以在下面的檔案中找到它。按照我們的 快速且簡單的 Ubuntu 安裝教學課程.
|
1 |
curl -o gpl.txt https://www.gnu.org/licenses/gpl-3.0.txt |

接下來,您可以使用 grep 進行基本的文字搜尋:
|
1 |
grep <pattern> <text_file> |

可以將指令的輸出透過管線(pipe)傳送給 grep:
|
1 |
cat gpl.txt | grep <pattern> |
區分大小寫
預設情況下,grep 會區分大小寫。在許多情況下,忽略大小寫可能是最佳選擇。若要停用區分大小寫的搜尋,請使用「-i」或「–ignore-case」旗標:
|
1 2 3 |
$ grep -i <pattern> <file> $ grep --ignore-case <pattern> <flag> |
反向尋找
預設情況下,grep 的行為是列印找到模式的行。反向比對是指當您不想看到與模式相符的行時的現象。為了進行反向比對,您需要使用「-v」或「–invert-match」旗標:
|
1 2 3 |
$ grep -v <pattern> <file> $ grep --invert-match <pattern> <file> |
行號
在非常大的檔案上執行 grep 時,很難追蹤搜尋結果的位置。為了讓事情變得更容易,grep 具有顯示行號的功能。若要啟用行號顯示,請使用「-n」或「–line-number」旗標:
|
1 2 3 |
grep -n <pattern> <file> grep --line-number <pattern> <file> |

可以組合多個 grep 引數。以下 grep 指令將在列印行號的同時執行反向比對:
|
1 |
grep -nv <pattern> <file> |

正規表示式
在本指南的開頭,我們提到 grep 代表全域正規表示式列印(global regular expression print)。術語 「正規表示式」 被定義為描述搜尋模式的特殊字串。正規表示式有其自己的結構 and 規則。
有許多字串搜尋演算法和工具使用正規表示式(簡稱 regex)來執行搜尋和取代操作。雖然它很流行,但不同的應用程式和程式語言對 regex 的實作略有不同。在本節中,我們將展示一些使用 grep 的 regex 方法。
字面值比對
在先前的 grep 範例中,grep 在指定的文字檔案中搜尋特定字串。Grep 實際上是使用非常基本的正規表示式進行搜尋。定義搜尋給定字串精確比對的 regex 模式稱為「字面值(literals)」。這個名稱源於它們逐個字元地字面比對模式。
字面比對適用於字母和數字字元(以及某些特殊字元)。然而,根據其他運算式機制,此行為可能會改變:
|
1 |
grep "<string>" <file> |

錨點比對
錨點是用於定義比對位置必須在行中何處才能算作有效比對的特殊字元。這裡有一個簡單的範例。如果我們只想尋找以字串「GNU」開頭的行,那麼使用正規表示式的 grep 將如下所示。在這裡,字元「^」是錨點,定義只有在行首的比對才是有效的:
|
1 |
grep -n "^GNU" <file> |

同樣地,如果我們只想尋找以字串「works」結尾的行,那麼使用正規表示式的 grep 將如下所示。在這裡,字元「$」是錨點,定義只有在行尾的比對才是有效的:
|
1 |
grep -n "and$" <file> |

任意字元比對
進行文字搜尋時,您可能希望定義在特定位置可以是任何字元。在正規表示式中,這由句點字元 (.) 表示。
看看這個範例。在 GNU GPL 3 文字檔案中,單字「accept」和「except」都有共同的部分「cept」。此外,這兩個單字在「cept」部分之前都有兩個字元。以下 grep 指令將比對在「cept」部分之前有兩個字元的任何單字:
|
1 |
grep -n "..cept" <file> |

根據此正規表示式,其他單字如 suscept、unaccept、unexpected 等也是有效的比對。
中括號
在正規表示式中,中括號運算式定義了在指定位置可以是中括號內宣告的任何字元。看看以下正規表示式字串:
|
1 |
t[wo]o |
實際應用時,單字 too 和 two 將是有效的比對:
|
1 |
grep -n "t[wo]o" <file> |

中括號運算式開啟了一些有趣的可能性。可以使用中括號運算式來表示在指定位置可以是除中括號內宣告的字元之外的任何字元。看看以下正規表示式字串。只有在「ode」之前有除「c」之外的任何字元時,比對才有效:
|
1 |
"[^c]ode" |
在 GPL-3 授權條款文字檔案上執行它:
|
1 |
grep -n "[^c]ode" <file> |

除了檔案中的結果外,其他有效的結果還有 node、abode、anode 等。中括號運算式也可以描述字元範圍。以下正規表示式表示如果行首是大寫字元,則比對有效:
|
1 |
"^[A-Z]" |
在 GPL-3 授權條款文字檔案上執行它。結果將是文字檔案中的所有行:
|
1 |
grep -n "^[A-Z]" <file> |

為了便於使用,某些字元類別具有指定的標籤。在先前的範例中,我們使用範圍「A-Z」來定義大寫字元。相反地,我們也可以使用「[:upper:]」。結果將會相同:
|
1 |
grep -n "^[[:upper:]]" <file> |
重複模式
在某些情況下,您可能希望比對特定模式或正規表示式零次或多次。為此,元字元是星號 (*)。以下正規表示式將比對所有僅包含字母且其間只有單個空格的括號。請注意,小寫、大寫字元集和空格的宣告是連在一起的,沒有任何標點符號:
|
1 |
"([a-zA-Z ]*)" |
使用 grep 實際執行該正規表示式:
|
1 |
grep -n "([A-Za-z ]*)" <file> |
將元字元用作字面字元
到目前為止,我們已經認識了各種元字元,例如星號 (*)、句點 (.)、錨點 (^ 和 $) 等。在正規表示式中,它們各自代表一個獨特的功能。當需要將它們用作字面值,而不是元字元時,問題就來了。在這種情況下,在元字元前面加上反斜線 (\) 將表示它將以字面意義使用,而不是作為元字元。看看這個正規表示式範例。它將比對所有以大寫字母開頭並以句點結尾的行:
|
1 |
grep -n "^[A-Z].*\.$" <file> |
分支
使用括號運算式,我們可以為單個字元比對指定不同的可能選擇。正規表示式也具有對單字和片語執行相同操作的功能。為了表示分支,可以使用管道字元 (|)。這些選項保留在括號內,並由管道字元將它們彼此分隔。可以有兩個或多個可能的選項使比對有效。看看以下正規表示式範例。它將同時比對「GPL」和「General Public License」:
|
1 |
grep -nE "(GPL|General Public License)" <file> |
量詞
使用星號 (*) 元字元,我們能夠重複定義零次或多次模式。然而,還有更多可以使用的功能。用一個例子來解釋量詞會更容易。以下正規表示式說明了「copyright」和「right」都是有效的比對。問號 (?) 表示「copy」部分是可選的比對:
|
1 |
grep -nE "(copy)?right" <file> |

下一個量詞是加號 (+)。它的行為與星號類似。但是,定義的模式必須至少比對一次。在以下範例中,正規表示式將比對「soft」後面接一個或多個非空白字元:
|
1 |
grep -nE "soft[^[:space:]]+" <file> |
指定比對重複次數
可以指定比對重複的次數。為此,請使用大括號 ({})。以下正規表示式將比對任何包含至少三個母音的單字:
|
1 |
grep -nE "[aeiouAEIOU]{3}" <file> |

此功能還允許您定義比對長度的下限和上限。在以下範例中,正規表示式將比對任何長度為 10 到 15 個字元的單字:
|
1 |
grep -nE "[[:alpha:]]{10,15}" <file> |
結論
使用 grep 搜尋文字檔案非常方便。正規表示式使使用 grep 搜尋變得更有趣且更有用。它們還可以根據您的心願微調搜尋模式。
雖然我們已經展示了一些常見的正規表示式,但這只是個開始。還有更進階的正規表示式,可以對搜尋行為提供最精細的控制。除了 grep 之外,正規表示式也被其他工具和程式語言廣泛使用。
祝您使用愉快!







留言
目前尚無留言。成為第一個留言的人吧。