正則表達式使SED變得強大而高效。使用正則表達式可以解決許多復(fù)雜的任務(wù)。
本章分為三部分:標準正則表達式 , 正則表達式、POSIX正則表達示。
行首(^)? ? -? ?在正則表達式術(shù)語中,插入符(^)符號與行的開頭匹配。下面的示例打印以模式" The"開頭的所有行。
$sed -n '/^The/p' books.txt
執(zhí)行上述代碼后,您將得到以下輸出:
The Two Towers, J. R. R. Tolkien The Alchemist, Paulo Coelho The Fellowship of the Ring, J. R. R. Tolkien The Pilgrimage, Paulo Coelho
行尾($)? ? -? 行尾由dollar($)符號表示。下面的示例打印以" Coelho"結(jié)尾的行。
$sed -n '/Coelho$/p' books.txt
執(zhí)行上述代碼后,您將得到以下輸出:
The Alchemist, Paulo Coelho The Pilgrimage, Paulo Coelho
單個字符(.)? ? -? Dot(.)匹配行尾字符以外的任何單個字符。下面的示例顯示所有以字符" t"結(jié)尾的三個字母詞。
$echo -e "cat\nbat\nrat\nmat\nbatting\nrats\nmats" | sed -n '/^..t$/p'
執(zhí)行上述代碼后,您將得到以下輸出:
cat bat rat mat
匹配字符集([])? ? -? 在正則表達式術(shù)語中,字符集用方括號([])表示。僅用于匹配幾個字符中的一個。以下示例匹配模式" Call"和" Tall",但不匹配" Ball"。
$echo -e "Call\nTall\nBall" | sed -n '/[CT]all/p'
執(zhí)行上述代碼后,您將得到以下輸出:
Call Tall
排他集([^])? ? -? 在排他字符集中,插入號將否定在方括號中的字符集。以下示例僅打印"Ball"。
$echo -e "Call\nTall\nBall" | sed -n '/[^CT]all/p'
執(zhí)行上述代碼后,您將得到以下輸出:
Ball
字符范圍([-])? ? -? 提供字符范圍時,正則表達式匹配方括號中指定范圍內(nèi)的任何字符。以下示例匹配"Call"和"Tall",但不匹配"Ball"。
$echo -e "Call\nTall\nBall" | sed -n '/[C-Z]all/p'
執(zhí)行上述代碼后,您將得到以下輸出:
Call Tall
現(xiàn)在讓我們將范圍修改為" A-P"并觀察輸出。
$echo -e "Call\nTall\nBall" | sed -n '/[A-P]all/p'
執(zhí)行上述代碼后,您將得到以下輸出:
Call Ball
零出現(xiàn)一次(\?)? ? -? 在SED中,問號(\?)匹配零個或一個出現(xiàn)的前一個字符。下面的示例匹配"Behaviour"以及"Behavior"。在這里,我們使用"\?"將" u"作為可選字符。
$echo -e "Behaviour\nBehavior" | sed -n '/Behaviou\?r/p'
執(zhí)行上述代碼后,您將得到以下輸出:
Behaviour Behavior
一次或多次出現(xiàn)(\+)? ? -? 在SED中,加號(\+)與一個或多個出現(xiàn)的前一個字符匹配。以下示例匹配一個或多個出現(xiàn)的" 2"。
$echo -e "111\n22\n123\n234\n456\n222" | sed -n '/2\+/p'
執(zhí)行上述代碼后,您將得到以下輸出:
22 123 234 222
零次或多次發(fā)生(*)? ? ?-? 星號(*)與前面字符的零個或多個匹配。下面的示例匹配" ca"," cat"," catt"等。
$echo -e "ca\ncat" | sed -n '/cat*/p'
執(zhí)行上述代碼后,您將得到以下輸出:
ca cat
恰好N次出現(xiàn){n}? ? -? {n}精確匹配前一個字符的" n"次出現(xiàn)。以下示例僅打印三位數(shù)。但是在此之前,您需要創(chuàng)建以下僅包含數(shù)字的文件。
$cat numbers.txt
執(zhí)行上述代碼后,您將得到以下輸出:
1 10 100 1000 10000 100000 1000000 10000000 100000000 1000000000
讓我們編寫SED表達式。
$sed -n '/^[0-9]\{3\}$/p' numbers.txt
執(zhí)行上述代碼后,您將得到以下輸出:
100
請注意,一對花括號用"\"字符轉(zhuǎn)義。
至少發(fā)生n次{n,}? ? -? {n,}至少匹配前一個字符的" n"次出現(xiàn)。下面的示例打印所有大于或等于五位數(shù)的數(shù)字。
$sed -n '/^[0-9]\{5,\}$/p' numbers.txt
執(zhí)行上述代碼后,您將得到以下輸出:
10000 100000 1000000 10000000 100000000 1000000000
{m,n}至少m,最多n次? ? -? {m,n}至少匹配" m"個字符,并且最多匹配" n"個字符。下面的示例打印所有具有至少五位數(shù)但不超過八位數(shù)的數(shù)字。
$sed -n '/^[0-9]\{5,8\}$/p' numbers.txt
執(zhí)行上述代碼后,您將得到以下輸出:
10000 100000 1000000 10000000
管道(|)? ? ?-? 在SED中,管道字符的行為類似于邏輯OR操作。它匹配管道兩側(cè)的項目。以下示例匹配" str1"或" str3"。
$echo -e "str1\nstr2\nstr3\nstr4" | sed -n '/str\(1\|3\)/p'
執(zhí)行上述代碼后,您將得到以下輸出:
str1 str3
請注意,圓括號(|)對用"\"字符轉(zhuǎn)義。
有某些特殊字符。例如,換行符用"\n"表示,回車符用"\r"表示,依此類推。要將這些字符用于常規(guī)ASCIIcontext,我們必須使用反斜杠(\)字符對其進行轉(zhuǎn)義。
轉(zhuǎn)義"\"? ? -? 下面的示例匹配模式"\"。
$echo 'str1\str2' | sed -n '/\\/p'
執(zhí)行上述代碼后,您將得到以下輸出:
str1\str2
轉(zhuǎn)義"\n"? ? -? 下面的示例匹配換行符。
$echo 'str1\nstr2' | sed -n '/\\n/p'
執(zhí)行上述代碼后,您將得到以下輸出:
str1\nstr2
轉(zhuǎn)義"\r"? ? -? 以下示例匹配回車符。
$echo 'str1\rstr2' | sed -n '/\\r/p'
執(zhí)行上述代碼后,您將得到以下輸出:
str1\rstr2
轉(zhuǎn)義"\dnnn"? ? -? 這與一個十進制ASCII值為" nnn"的字符匹配。以下示例僅匹配字符" a"。
$echo -e "a\nb\nc" | sed -n '/\d97/p'
執(zhí)行上述代碼后,您將得到以下輸出:
a
轉(zhuǎn)義"\onnn"? ? -? 這與八進制ASCII值為" nnn"的字符匹配。以下示例僅匹配字符" b"。
$echo -e "a\nb\nc" | sed -n '/\o142/p'
執(zhí)行上述代碼后,您將得到以下輸出:
b
這與十六進制ASCII值為" nnn"的字符匹配。下面的示例僅匹配字符" c"。
$echo -e "a\nb\nc" | sed -n '/\x63/p'
執(zhí)行上述代碼后,您將得到以下輸出:
c
有些保留字具有特殊含義,這些保留字稱為正則表達式的POSIX類。
[:alnum:]? ? -? 它表示字母和數(shù)字字符。以下示例僅匹配"一個"和" 123",但不匹配制表符。
$echo -e "One\n123\n\t" | sed -n '/[[:alnum:]]/p'
執(zhí)行上述代碼后,您將得到以下輸出:
One 123
[:alpha:]? ? ?-? 它僅表示字母字符。下面的示例僅匹配單詞" One"。
$echo -e "One\n123\n\t" | sed -n '/[[:alpha:]]/p'
執(zhí)行上述代碼后,您將得到以下輸出:
One
[:blank:]? ? ?-? 它表示空白字符,可以是空格或制表符。下面的示例僅匹配制表符。
$echo -e "One\n123\n\t" | sed -n '/[[:blank:]]/p' | cat -vte
執(zhí)行上述代碼后,您將得到以下輸出:
^I$
請注意,命令" cat -vte"用于顯示制表符(^ I)。
[:digit:]? ? -? 它僅表示十進制數(shù)。以下示例僅匹配數(shù)字" 123"。
$echo -e "abc\n123\n\t" | sed -n '/[[:digit:]]/p'
執(zhí)行上述代碼后,您將得到以下輸出:
123
[:lower:]? ? -? 僅表示小寫字母。以下示例僅匹配"one"。
$echo -e "one\nTWO\n\t" | sed -n '/[[:lower:]]/p'
執(zhí)行上述代碼后,您將得到以下輸出:
one
[:upper:]? ? -? 它僅暗示大寫字母。以下示例僅匹配"TWO"。
$echo -e "one\nTWO\n\t" | sed -n '/[[:upper:]]/p'
執(zhí)行上述代碼后,您將得到以下輸出:
TWO
[:punct:]? ? -? 這意味著標點符號包括非空格或字母數(shù)字字符
$echo -e "One,Two\nThree\nFour" | sed -n '/[[:punct:]]/p'
執(zhí)行上述代碼后,您將得到以下輸出:
One,Two
[:space:]? ? -? 它暗示空白字符。以下示例說明了這一點。
$echo -e "One\n123\f\t" | sed -n '/[[:space:]]/p' | cat -vte
執(zhí)行上述代碼后,您將得到以下輸出:
123^L^I$
像傳統(tǒng)的正則表達式一樣,SED也支持元字符,這些是Perl樣式的正則表達式。
字邊界(\b)? ? -? 在正則表達式術(shù)語中,"\b"與單詞邊界匹配。例如,"\bthe\b"匹配" the",但不匹配" these"," there"," they"," then"等。以下示例說明了這一點。
$echo -e "these\nthe\nthey\nthen" | sed -n '/\bthe\b/p'
執(zhí)行上述代碼后,您將得到以下輸出:
the
非單詞邊界(\B)? ? -? 在正則表達式術(shù)語中,"\B"匹配非單詞邊界。例如," the\B"匹配" these"和" they",但不匹配" the"。以下示例說明了這一點。
$echo -e "these\nthe\nthey" | sed -n '/the\B/p'
執(zhí)行上述代碼后,您將得到以下輸出:
these they
單個空格(\s)? ? -? 在SED中,"\s"表示單個空格字符。以下示例匹配" Line\t1",但不匹配" Line1"。
$echo -e "Line\t1\nLine2" | sed -n '/Line\s/p'
執(zhí)行上述代碼后,您將得到以下輸出:
Line 1
單個非空白(\S)? ? -? 在SED中,"\S"表示單個空格字符。以下示例匹配" Line2",但不匹配" Line\t1"。
$echo -e "Line\t1\nLine2" | sed -n '/Line\S/p'
執(zhí)行上述代碼后,您將得到以下輸出:
Line2
單字字符(\w)? ? -? 在SED中,"\w"表示單個單詞字符,即字母字符,數(shù)字和下劃線(_)。以下示例說明了這一點。
$echo -e "One\n123\n1_2\n&;#" | sed -n '/\w/p'
執(zhí)行上述代碼后,您將得到以下輸出:
One 123 1_2
單個非單詞字符(\W)? ? -? 在SED中,"\W"表示單個非單詞字符,與"\w"完全相反。以下示例說明了這一點。
$echo -e "One\n123\n1_2\n&;#" | sed -n '/\W/p'
執(zhí)行上述代碼后,您將得到以下輸出:
&;#
在SED中,"\`"表示模式空間的開始。下面的示例僅匹配單詞" One"。
$echo -e "One\nTwo One" | sed -n '/\`One/p'
執(zhí)行上述代碼后,您將得到以下輸出:
One