sed是強大,高效的處理正規表示式。一些複雜的任務,可以解決簡單的正規表示式。任何命令列專家都知道正規表示式的威力。
本教學介紹了標準的正規表示式,POSIX類的正規表示式和元字元。考慮我們有一個文字檔案 books.txt 將被處理,它有以下內容:
A Storm of Swords, George R. R. Martin The Two Towers, J. R. R. Tolkien The Alchemist, Paulo Coelho The Fellowship of the Ring, J. R. R. Tolkien The Pilgrimage, Paulo Coelho A Game of Thrones, George R. R. Martin
插入符號(^)符號用於一行的開始匹配。下面的例子列印所有的啟動與模式“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
字元集是用方括號([])表示。它用來匹配只有1個之中的幾個字元。下面的例子匹配模式“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
問號(\?)匹配零個或一個匹配前面的字元。下面的例子匹配“Behaviour”和“Behavior”。在這裡,我們通過使用“\?”使“u”作為一個可選的字元。
[jerry]$ echo -e "Behaviour\nBehavior" | sed -n '/Behaviou\?r/ p'
執行上面的程式碼,會得到如下結果:
Behaviour Behavior
加號(\+)匹配前面的字元出現一次或多次。下面的例子匹配“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”出現前面的字元。下面的例子列印只有三個數位。但在這之前,你需要建立以下檔案,該檔案僅包含數位。考慮 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”出現前面的字元。下面的例子列印大於或等於5個數位的所有數位。
[jerry]$ sed -n '/^[0-9]\{5,\}$/ p' numbers.txt
執行上面的程式碼,會得到如下結果:
10000 100000 1000000 10000000 100000000 1000000000
{m, n} 表示式匹配,至少是“M”和最“N”出現前面的字元。下面的例子列印所有具有至少5個數位,但不超過8位元的數位。
[jerry]$ sed -n '/^[0-9]\{5,8\}$/ p' numbers.txt
執行上面的程式碼,會得到如下結果:
10000 100000 1000000 10000000
管道符的行為類似於邏輯或運算。它從管的兩側相匹配的條目。下面的例子要麼匹配"str1" 和 "str3"。這裡,一對括號和管道 (|) 由“\”字元跳脫。
[jerry]$ echo -e "str1\nstr2\nstr3\nstr4" | sed -n '/str\(1\|3\)/ p'
執行上面的程式碼,會得到如下結果:
str1 str3
有哪些有在Sed有特殊含義的特殊字元。例如,用“\n”表示換行,回車被為“\r”表示,依此類推。要使用這些字元轉換成普通的ASCII,我們必須使用反斜槓(\)字元跳脫。本章說明了跳脫特殊字元。
下面的例子匹配的模式“\”。
[jerry]$ echo 'str1\str2' | sed -n '/\\/ p'
執行上面的程式碼,會得到如下結果:
str1\str2
下面的範例將新行字元匹配。
[jerry]$ echo 'str1\nstr2' | sed -n '/\\n/ p'
執行上面的程式碼,會得到如下結果:
str1\nstr2
下面的例子回車匹配。
[jerry]$ echo 'str1\rstr2' | sed -n '/\\r/ p'
執行上面的程式碼,會得到如下結果:
str1\rstr2
這個匹配一個字元的十進位制ASCII碼值是“nnn”。下面的例子中只匹配字元“a”。
[jerry]$ echo -e "a\nb\nc" | sed -n '/\d97/ p'
執行上面的程式碼,會得到如下結果:
a
這個匹配字元的八進位制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
有哪些有Sed 特殊的含義一定的保留字。這些保留字被稱為POSIX類正規表示式。本節介紹Sed支援POSIX類。
這意味著按字母和數位字元。下面的例子只匹配“One”和“123”,但不匹配製表符。
[jerry]$ echo -e "One\n123\n\t" | sed -n '/[[:alnum:]]/ p'
執行上面的程式碼,會得到如下結果:
One 123
這意味著只有字母字元。下面的例子只匹配單詞“One”。
[jerry]$ echo -e "One\n123\n\t" | sed -n '/[[:alpha:]]/ p'
執行上面的程式碼,會得到如下結果:
One
這意味著空白字元可以是任何空格或製表符。下面的例子只匹配製表符。
[jerry]$ echo -e "One\n123\n\t" | sed -n '/[[:space:]]/ p' | cat -vte
執行上面的程式碼,會得到如下結果:
^I$
注意,該命令“cat -vte”用於顯示製表符(^ I)中。
這意味著只有小數。下面的例子只匹配數位“123”。
[jerry]$ echo -e "abc\n123\n\t" | sed -n '/[[:digit:]]/ p'
執行上面的程式碼,會得到如下結果:
123
這意味著只有小寫字母。下面的例子只匹配“one”。
[jerry]$ echo -e "one\nTWO\n\t" | sed -n '/[[:lower:]]/ p'
執行上面的程式碼,會得到如下結果:
one
這意味著只有大寫字母。下面的例子只匹配 "TWO".
[jerry]$ echo -e "one\nTWO\n\t" | sed -n '/[[:upper:]]/ p'
執行上面的程式碼,會得到如下結果:
TWO
它意味著標點符號包括非空格或字母數位字元
[jerry]$ echo -e "One,Two\nThree\nFour" | sed -n '/[[:punct:]]/ p'
執行上面的程式碼,會得到如下結果:
One,Two
這意味著空格字元。下面的例子說明了這一點。
[jerry]$ echo -e "One\n123\f\t" | sed -n '/[[:space:]]/ p' | cat -vte
執行上面的程式碼,會得到如下結果:
123^L^I$
像傳統的正規表示式,Sed也支援特殊字元。這些是Perl風格正規表示式。需要注意的是元字元的支援是GNU Sed,可能無法與Sed的其他變種的工作。讓我們詳細討論的元字元。
“\b”元字元的字邊界匹配。例如,“\bthe\b”匹配“the”而不是"these", "there", "they", "then", 依此類推。下面的例子說明了這一點。
[jerry]$ echo -e "these\nthe\nthey\nthen" | sed -n '/\bthe\b/ p'
執行上面的程式碼,會得到如下結果:
the
“\B”元字元匹配非單詞邊界。例如,“the\B”匹配“,這些”these“和“they”而不是“the”。下面的例子說明了這一點。
[jerry]$ echo -e "these\nthe\nthey" | sed -n '/the\B/ p'
執行上面的程式碼,會得到如下結果:
these they
“\s”元字元意味著單個空格字元。下面的例子匹配“Line\t1”,但不匹配“Line1”。
[jerry]$ echo -e "Line\t1\nLine2" | sed -n '/Line\s/ p'
執行上面的程式碼,會得到如下結果:
Line 1
“\S”元字元意味著單個空格字元。下面的例子匹配“Line2”,但不匹配“Line\t1”。
[jerry]$ echo -e "Line\t1\nLine2" | sed -n '/Line\S/ p'
執行上面的程式碼,會得到如下結果:
Line2
“\W”元字元意味著單個單詞字元,即字母字元,數位和下劃線(_)。下面的例子說明了這一點。
[jerry]$ echo -e "One\n123\n1_2\n&;#" | sed -n '/\w/ p'
執行上面的程式碼,會得到如下結果:
One 123 1_2
“\W”元字元意味著一個非單詞字元,以“\w”正好相反。下面的例子說明了這一點。
[jerry]$ echo -e "One\n123\n1_2\n&;#" | sed -n '/\W/ p'
On executing the above code, you get the following result:
&;#
“\”'元字元意味著將模式空間的開始位置。下面的例子只匹配單詞“One”。
[jerry]$ echo -e "One\nTwo One" | sed -n '/\`One/ p'
執行上面的程式碼,會得到如下結果:
One