跳轉到內容

Awk 入門/搜尋模式 (1)

來自 Wikibooks,開放世界中的開放書籍

如你所知,Awk 會逐行遍歷檔案,並對匹配搜尋模式的每一行執行程式碼塊。到目前為止,我們只使用了非常簡單的搜尋模式,例如 /gold/,但你現在將學習更高階的搜尋模式。本頁上的搜尋模式被稱為正則表示式。正則表示式是一組規則,可以匹配特定的字元序列。

簡單模式

[編輯 | 編輯原始碼]

可以指定的 最簡單 的搜尋模式型別是簡單字串,用正斜槓 (/) 括起來。例如

/The/

這會搜尋包含字串 "The" 的任何行。這不會匹配 "the",因為 Awk 是區分大小寫的,但它會匹配像 "There" 或 "Them" 這樣的單詞。

這是最原始的搜尋模式。Awk 定義了特殊字元或元字元,可以用來使搜尋更具體。例如,在字串前面加上 ^ ("插入符號") 會告訴 Awk 在輸入行的開頭搜尋字串。例如

/^The/

這會匹配任何以字串 "The" 開頭的行。包含 "The" 但不以其開頭的行將不會匹配。

類似地,在字串後面加上 $ 會匹配任何以搜尋模式結尾的行。例如

/The$/

在本例中,不以 "The" 結尾的行將不會匹配。

但是,如果我們實際上想在文字中搜索 ^$ 這樣的字元呢?很簡單,我們只需在字元前面加上反斜槓 (\) 即可。例如

/\$/

這將匹配任何包含 "$" 的行。

有許多不同的元字元可用於自定義搜尋模式。

字元集

[編輯 | 編輯原始碼]

可以使用方括號 ([]) 指定一組備選字元

/[Tt]he/ 

此示例匹配字串 "The" 和 "the"。還可以指定字元範圍。例如

/[a-z]/

這會匹配 "a" 到 "z" 之間的任何字元,以及

/[a-zA-Z0-9]/

這會匹配任何字母或數字。

還可以透過在範圍前面加上 ^ 來排除字元範圍。這與匹配字串開頭的插入符號不同,因為它位於方括號內。例如

/^[^a-zA-Z0-9]/

這會匹配任何以字母或數字開頭的行。實際上,你可以在字元集中包含插入符號,確保它不是列出的第一個字元。

豎線 (|) 允許將正則表示式進行邏輯 OR 操作。例如

/(^Germany)|(^Netherlands)/

這會匹配以單詞 "Germany" 單詞 "Netherlands" 開頭的行。請注意如何使用括號對這兩個表示式進行分組。

萬用字元

[編輯 | 編輯原始碼]

點 (.) 允許 "萬用字元" 匹配,這意味著它可以用於指定任何任意字元。例如

/f.n/

這將匹配 "fan"、"fun"、"fin",以及 "fxn"、"f4n",以及任何其他以 f 開頭,一個字元,然後以 n 結尾的字串。

這種點萬用字元的使用對於 UNIX shell 使用者來說應該很熟悉,但 Awk 對 * 萬用字元的解釋略有不同。在 UNIX shell 中,* 會替換為任意長度的任意字元字串,包括零,而在 Awk 中,* 只會匹配前一個字元或表示式的零次或多次重複。例如,"a*" 會匹配 "a"、"aa"、"aaa" 等。這意味著 ".*" 會匹配任何字元字串。作為一個更復雜的示例,

/(ab|c)*/

這會匹配 "ab"、"abab"、"ababab"、"c"、"cc"、"ccc",甚至 "abc"、"ababc"、"cabcababc",或任何其他類似的組合。

還有其他字元允許匹配重複的字元。? 匹配前一個正則表示式的正好零次或一次出現,而 + 匹配前一個正則表示式的 一次或多次出現。例如

/^[+-]?[0-9]+$/

這會匹配任何只包含(可能帶符號的)整數的 行。這是一個有點令人困惑的例子,將其分解成部分是有幫助的

  • ^ 在行的開頭查詢字串。
  • [+-]? 指定數字可能的 "+" 或 "-" 符號。
  • [0-9]+ 指定至少一位數字 "0" 到 "9"。
  • $ 指定行以數字結尾。

特定重複

[編輯 | 編輯原始碼]

雖然這種語法由 Single Unix Specification 定義,但許多 awk 沒有實現此功能。在 GNU Awk 4.0 之前的版本中,你需要—posix 或—re-interval 選項來啟用它。

如果要將正則表示式匹配特定次數,可以使用花括號 ({})。例如

/f[eo]{2}t/

這會匹配 "foot" 或 "feet"。

要指定數字為最小值,請在後面加上逗號。

/[0-9]{3,}/

這會匹配至少三位數的數字。這是編寫以下程式碼的更簡單的方法

/[0-9][0-9][0-9]+/

可以在花括號中放置兩個用逗號分隔的數字來指定一個範圍。

/^[0-9]{4,7}$/

這會匹配包含 4 位、5 位、6 位或 7 位數字的行。數字過多或不足,則不會匹配。

除非你已經熟悉正則表示式,否則你應該嘗試編寫一些自己的正則表示式。為了檢視你是否寫對了,可以編寫一個簡單的 Awk 程式來列印任何匹配表示式的行,並測試它。

  1. 編寫一個正則表示式來匹配郵政編碼。美國郵政編碼由 5 位數字和可選的連字元以及另外 4 位數字組成。
  2. 編寫一個正則表示式來匹配任何數字,包括可選的小數點後跟更多數字。
  3. 編寫一個正則表示式來查詢電子郵件地址。查詢有效的字元(字母、數字、點和下劃線),後跟 "@",然後是更多有效的字元,至少包含一個點。
  4. 編寫一個正則表示式來匹配電話號碼。它應該處理區號、分機號,以及可選的連字元和括號來對數字進行分組。確保它不會匹配過長或過短的電話號碼。

在下一頁中,你將學習其他型別的搜尋模式。

華夏公益教科書