流編輯器 - 正則表示式



正是正則表示式使得 SED 強大而高效。許多複雜的任務都可以用正則表示式來解決。任何命令列專家都知道正則表示式的威力。

與許多其他 GNU/Linux 實用程式一樣,SED 也支援正則表示式,通常稱為regex。本章詳細介紹了正則表示式。本章分為三個部分:標準正則表示式、POSIX 正則表示式類和元字元。

標準正則表示式

行首 (^)

在正則表示式術語中,插入符號 (^) 匹配行的開頭。以下示例列印所有以模式“The”開頭的行。

[jerry]$ sed -n '/^The/ p' books.txt

執行上述程式碼後,您將獲得以下結果

The Two Towers, J. R. R. Tolkien 
The Alchemist, Paulo Coelho 
The Fellowship of the Ring, J. R. R. Tolkien 
The Pilgrimage, Paulo Coelho

行尾 ($)

行尾由美元符號 ($) 表示。以下示例列印以“Coelho”結尾的行。

[jerry]$ sed -n '/Coelho$/ p' books.txt 

執行上述程式碼後,您將獲得以下結果

The Alchemist, Paulo Coelho 
The Pilgrimage, Paulo Coelho

單個字元 (.)

點 (.) 匹配任何單個字元,除了行尾字元。以下示例列印所有以字元“t”結尾的三個字母的單詞。

[jerry]$ echo -e "cat\nbat\nrat\nmat\nbatting\nrats\nmats" | sed -n '/^..t$/p' 

執行上述程式碼後,您將獲得以下結果

cat 
bat 
rat 
mat

匹配字元集 ([])

在正則表示式術語中,字元集由方括號 ([]) 表示。它用於匹配多個字元中的一個。以下示例匹配模式“Call”和“Tall”,但不匹配“Ball”。

[jerry]$ echo -e "Call\nTall\nBall" | sed -n '/[CT]all/ p'

執行上述程式碼後,您將獲得以下結果

Call 
Tall

排除集 ([^])

在排除集中,插入符號否定方括號中字元集。以下示例僅列印“Ball”。

[jerry]$ echo -e "Call\nTall\nBall" | sed -n '/[^CT]all/ p'

執行上述程式碼後,您將獲得以下結果

Ball 

字元範圍 ([-])

當提供字元範圍時,正則表示式將匹配方括號中指定的範圍內的任何字元。以下示例匹配“Call”和“Tall”,但不匹配“Ball”。

[jerry]$ echo -e "Call\nTall\nBall" | sed -n '/[C-Z]all/ p' 

執行上述程式碼後,您將獲得以下結果

Call 
Tall

現在讓我們將範圍修改為“A-P”並觀察結果。

[jerry]$ echo -e "Call\nTall\nBall" | sed -n '/[A-P]all/ p' 

執行上述程式碼後,您將獲得以下結果

Call 
Ball

零次或一次出現 (\?)

在 SED 中,問號 (?) 匹配前面字元的零次或一次出現。以下示例匹配“Behaviour”以及“Behavior”。在這裡,我們使用“\?”將“u”作為可選字元。

[jerry]$ echo -e "Behaviour\nBehavior" | sed -n '/Behaviou\?r/ p' 

執行上述程式碼後,您將獲得以下結果

Behaviour 
Behavior

一次或多次出現 (\+)

在 SED 中,加號 (+) 匹配前面字元的一次或多次出現。以下示例匹配“2”的一次或多次出現。

[jerry]$ echo -e "111\n22\n123\n234\n456\n222"  | sed -n '/2\+/ p'

執行上述程式碼後,您將獲得以下結果

22 
123 
234 
222 

零次或多次出現 (*)

星號 (*) 匹配前面字元的零次或多次出現。以下示例匹配“ca”、“cat”、“catt”等。

[jerry]$ echo -e "ca\ncat" | sed -n '/cat*/ p' 

執行上述程式碼後,您將獲得以下結果

ca 
cat 

恰好 N 次出現 {n}

{n} 恰好匹配前面字元的“n”次出現。以下示例僅列印三位數。但在此之前,您需要建立以下僅包含數字的檔案。

[jerry]$ cat numbers.txt 

執行上述程式碼後,您將獲得以下結果

1 
10 
100 
1000 
10000 
100000 
1000000 
10000000 
100000000 
1000000000

讓我們編寫 SED 表示式。

[jerry]$ sed -n '/^[0-9]\{3\}$/ p' numbers.txt 

執行上述程式碼後,您將獲得以下結果

100

請注意,花括號對由“\”字元轉義。

至少 n 次出現 {n,}

{n,} 匹配前面字元的至少“n”次出現。以下示例列印所有大於或等於五位數的數字。

[jerry]$ sed -n '/^[0-9]\{5,\}$/ p' numbers.txt

執行上述程式碼後,您將獲得以下結果

10000 
100000 
1000000
10000000 
100000000 
1000000000 

M 到 N 次出現 {m, n}

{m, n} 匹配前面字元的至少“m”次,最多“n”次出現。以下示例列印所有至少有五位數但不多於八位數的數字。

[jerry]$ sed -n '/^[0-9]\{5,8\}$/ p' numbers.txt

執行上述程式碼後,您將獲得以下結果

10000 
100000 
1000000 
10000000 

管道 (|)

在 SED 中,管道字元的行為類似於邏輯 OR 操作。它匹配管道兩側的專案。以下示例匹配“str1”或“str3”。

[jerry]$ echo -e "str1\nstr2\nstr3\nstr4" | sed -n '/str\(1\|3\)/ p' 

執行上述程式碼後,您將獲得以下結果

str1 
str3

請注意,括號對和管道 (|) 由“\”字元轉義。

跳脫字元

某些字元是特殊字元。例如,換行符由“\n”表示,回車符由“\r”表示,依此類推。要在常規 ASCII 上下文中使用這些字元,我們必須使用反斜槓 (\) 字元對其進行轉義。本章說明了特殊字元的轉義。

轉義“\”

以下示例匹配模式“\”。

[jerry]$ echo 'str1\str2' | sed -n '/\\/ p'

執行上述程式碼後,您將獲得以下結果

str1\str2 

轉義“\n”

以下示例匹配換行符。

[jerry]$ echo 'str1\nstr2' | sed -n '/\\n/ p'

執行上述程式碼後,您將獲得以下結果

str1\nstr2

轉義“\r”

以下示例匹配回車符。

[jerry]$ echo 'str1\rstr2' | sed -n '/\\r/ p'

執行上述程式碼後,您將獲得以下結果

str1\rstr2

轉義“\dnnn”

這匹配十進位制 ASCII 值為“nnn”的字元。以下示例僅匹配字元“a”。

[jerry]$ echo -e "a\nb\nc" | sed -n '/\d97/ p'

執行上述程式碼後,您將獲得以下結果

a

轉義“\onnn”

這匹配八進位制 ASCII 值為“nnn”的字元。以下示例僅匹配字元“b”。

[jerry]$ echo -e "a\nb\nc" | sed -n '/\o142/ p' 

執行上述程式碼後,您將獲得以下結果

b 

這匹配十六進位制 ASCII 值為“nnn”的字元。以下示例僅匹配字元“c”。

[jerry]$ echo -e "a\nb\nc" | sed -n '/\x63/ p'

執行上述程式碼後,您將獲得以下結果

c

POSIX 正則表示式類

某些保留字具有特殊含義。這些保留字稱為 POSIX 正則表示式類。本節介紹 SED 支援的 POSIX 類。

[:alnum:]

它表示字母數字字元。以下示例僅匹配“One”和“123”,但不匹配製表符。

[jerry]$ echo -e "One\n123\n\t" | sed -n '/[[:alnum:]]/ p'

執行上述程式碼後,您將獲得以下結果

One 
123

[:alpha:]

它僅表示字母字元。以下示例僅匹配單詞“One”。

[jerry]$ echo -e "One\n123\n\t" | sed -n '/[[:alpha:]]/ p'

執行上述程式碼後,您將獲得以下結果

One 

[:blank:]

它表示空格字元,可以是空格或製表符。以下示例僅匹配製表符。

[jerry]$ echo -e "One\n123\n\t" | sed -n '/[[:space:]]/ p' | cat -vte

執行上述程式碼後,您將獲得以下結果

^I$

請注意,命令“cat -vte”用於顯示製表符 (^I)。

[:digit:]

它僅表示十進位制數字。以下示例僅匹配數字“123”。

[jerry]$ echo -e "abc\n123\n\t" | sed -n '/[[:digit:]]/ p' 

執行上述程式碼後,您將獲得以下結果

123 

[:lower:]

它僅表示小寫字母。以下示例僅匹配“one”。

[jerry]$ echo -e "one\nTWO\n\t" | sed -n '/[[:lower:]]/ p' 

執行上述程式碼後,您將獲得以下結果

one 

[:upper:]

它僅表示大寫字母。以下示例僅匹配“TWO”。

[jerry]$ echo -e "one\nTWO\n\t" | sed -n '/[[:upper:]]/ p'

執行上述程式碼後,您將獲得以下結果

TWO

[:punct:]

它表示標點符號,包括非空格或字母數字字元

[jerry]$ echo -e "One,Two\nThree\nFour" | sed -n '/[[:punct:]]/ p'

執行上述程式碼後,您將獲得以下結果

One,Two

[:space:]

它表示空格字元。以下示例說明了這一點。

[jerry]$ echo -e "One\n123\f\t" | sed -n '/[[:space:]]/ p' | cat -vte 

執行上述程式碼後,您將獲得以下結果

123^L^I$ 

元字元

與傳統正則表示式一樣,SED 也支援元字元。這些是 Perl 風格的正則表示式。請注意,元字元支援是 GNU SED 特定的,可能不適用於其他 SED 變體。讓我們詳細討論元字元。

單詞邊界 (\b)

在正則表示式術語中,“\b”匹配單詞邊界。例如,“\bthe\b”匹配“the”,但不匹配“these”、“there”、“they”、“then”等。以下示例說明了這一點。

[jerry]$ echo -e "these\nthe\nthey\nthen" | sed -n '/\bthe\b/ p'

執行上述程式碼後,您將獲得以下結果

the

非單詞邊界 (\B)

在正則表示式術語中,“\B”匹配非單詞邊界。例如,“the\B”匹配“these”和“they”,但不匹配“the”。以下示例說明了這一點。

[jerry]$ echo -e "these\nthe\nthey" | sed -n '/the\B/ p'

執行上述程式碼後,您將獲得以下結果

these 
they

單個空格 (\s)

在 SED 中,“\s”表示單個空格字元。以下示例匹配“Line\t1”,但不匹配“Line1”。

[jerry]$ echo -e "Line\t1\nLine2" | sed -n '/Line\s/ p'

執行上述程式碼後,您將獲得以下結果

Line 1 

單個非空格 (\S)

在 SED 中,“\S”表示單個空格字元。以下示例匹配“Line2”,但不匹配“Line\t1”。

[jerry]$ echo -e "Line\t1\nLine2" | sed -n '/Line\S/ p' 

執行上述程式碼後,您將獲得以下結果

Line2

單個單詞字元 (\w)

在 SED 中,“\w”表示單個單詞字元,即字母字元、數字和下劃線 (_) 。以下示例說明了這一點。

[jerry]$ echo -e "One\n123\n1_2\n&;#" | sed -n '/\w/ p'

執行上述程式碼後,您將獲得以下結果

One 
123 
1_2

單個非單詞字元 (\W)

在 SED 中,“\W”表示單個非單詞字元,這與“\w”正好相反。以下示例說明了這一點。

[jerry]$ echo -e "One\n123\n1_2\n&;#" | sed -n '/\W/ p'

執行上述程式碼後,您將獲得以下結果

&;#

模式空間的開頭 (\`)

在 SED 中,“\`”表示模式空間的開頭。以下示例僅匹配單詞“One”。

[jerry]$ echo -e "One\nTwo One" | sed -n '/\`One/ p' 

執行上述程式碼後,您將獲得以下結果

One
廣告