正則表達(dá)式
1、純文本
$ echo "This is a test" | sed -n '/test/p'
This is a test
$ echo "This is a test" | sed -n '/trial/p'
$
$ echo "This is a test" | gawk '/test/{print $0}'
This is a test
$ echo "This is a test" | gawk '/trial/{print $0}'
第一個(gè)模式定義了一個(gè)單詞test喇肋。 sed編輯器和gawk程序腳本用它們各自的print命令打印出
匹配該正則表達(dá)式模式的所有行。由于echo語(yǔ)句在文本字符串中包含了單詞test,數(shù)據(jù)流文本能
夠匹配所定義的正則表達(dá)式模式往产,因此sed編輯器顯示了該行。
2某宪、可以在正則表達(dá)式中使用空格和數(shù)字
在正則表達(dá)式中仿村,空格和其他的字符并沒(méi)有什么區(qū)別。
$ echo "This is line number1" | sed -n '/ber 1/p'
如果你在正則表達(dá)式中定義了空格兴喂,那么它必須出現(xiàn)在數(shù)據(jù)流中蔼囊。甚至可以創(chuàng)建匹配多個(gè)連
續(xù)空格的正則表達(dá)式模式。
$ cat data1
This is a normal line of text.
This is a line with too many spaces.
$ sed -n '/ /p' data1
This is a line with too many spaces.
單詞間有兩個(gè)空格的行匹配正則表達(dá)式模式衣迷。這是用來(lái)查看文本文件中空格問(wèn)題的好辦法畏鼓。
3、特殊字符
正則表達(dá)式中的特殊字符:.*[]^${}+?|()
如果要查找文本中的美元符壶谒,只要在它前面加個(gè)反斜線(xiàn)云矫。
$ cat data2
The cost is $4.00
$ sed -n '/\$/p' data2
The cost is $4.00
由于反斜線(xiàn)是特殊字符,如果要在正則表達(dá)式模式中使用它汗菜,你必須對(duì)其轉(zhuǎn)義泼差,這樣就產(chǎn)生
了兩個(gè)反斜線(xiàn)。
$ echo "\ is a special character" | sed -n '/\\/p'
\ is a special character
最終呵俏,盡管正斜線(xiàn)不是正則表達(dá)式的特殊字符堆缘,但如果它出現(xiàn)在sed編輯器或gawk程序的正
則表達(dá)式中,你就會(huì)得到一個(gè)錯(cuò)誤普碎。
$ echo "3 / 2" | sed -n '///p'
sed: -e expression #1, char 2: No previous regular expression
要使用正斜線(xiàn)吼肥,也需要進(jìn)行轉(zhuǎn)義。
$ echo "3 / 2" | sed -n '/\//p'
3 / 2
現(xiàn)在sed編輯器能正確解釋正則表達(dá)式模式了,一切都很順利缀皱。
4斗这、錨字符
4.1、鎖定在行首
脫字符會(huì)在每個(gè)由換行符決定的新數(shù)據(jù)行的行首檢查模式啤斗。
$ cat data3
This is a test line.
this is another test line.
A line that tests this feature.
Yet more testing of this
$ sed -n '/^this/p' data3
this is another test line.
只要模式出現(xiàn)在新行的行首表箭,脫字符就能夠發(fā)現(xiàn)它。
如果你將脫字符放到模式開(kāi)頭之外的其他位置钮莲,那么它就跟普通字符一樣免钻,不再是特殊字符了:
$ echo "This ^ is a test" | sed -n '/s ^/p'
This ^ is a test
由于脫字符出現(xiàn)在正則表達(dá)式模式的尾部, sed編輯器會(huì)將它當(dāng)作普通字符來(lái)匹配崔拥。
4.2极舔、鎖定在行尾
跟在行首查找模式相反的就是在行尾查找。特殊字符美元符( $)定義了行尾錨點(diǎn)链瓦。將這個(gè)
特殊字符放在文本模式之后來(lái)指明數(shù)據(jù)行必須以該文本模式結(jié)尾拆魏。
$ echo "This is a good book" | sed -n '/book$/p'
This is a good book
$ echo "This book is good" | sed -n '/book$/p'
4.3、組合使用
第二種情況乍一看可能有些怪異慈俯,但極其有用渤刃。將兩個(gè)錨點(diǎn)直接組合在一起,之間不加任何
文本贴膘,這樣過(guò)濾出數(shù)據(jù)流中的空白行溪掀。考慮下面這個(gè)例子步鉴。
$ cat data5
This is one test line.
This is another test line.
$ sed '/^$/d' data5
This is one test line.
This is another test line.
5、點(diǎn)號(hào)字符
來(lái)看一些在正則表達(dá)式模式中使用點(diǎn)號(hào)字符的例子璃哟。
$ cat data6
This is a test of a line.
The cat is sleeping.
That is a very nice hat.
This test is at line four.
at ten o'clock we'll go home.
$ sed -n '/.at/p' data6
The cat is sleeping.
That is a very nice hat.
This test is at line four.
你應(yīng)該能夠明白為什么第一行無(wú)法匹配氛琢,而第二行和第三行就可以。第四行有點(diǎn)復(fù)雜随闪。注意阳似,
我們匹配了at,但在at前面并沒(méi)有任何字符來(lái)匹配點(diǎn)號(hào)字符铐伴。其實(shí)是有的撮奏!在正則表達(dá)式中,
空格也是字符当宴,因此at前面的空格剛好匹配了該模式畜吊。第五行證明了這點(diǎn),將at放在行首就不
會(huì)匹配該模式了户矢。
6玲献、字符組
下面是個(gè)創(chuàng)建字符組的例子。
$ sed -n '/[ch]at/p' data6
The cat is sleeping.
That is a very nice hat.
這里用到的數(shù)據(jù)文件和點(diǎn)號(hào)特殊字符例子中的一樣,但得到的結(jié)果卻不一樣捌年。這次我們成功
濾掉了只包含單詞at的行瓢娜。匹配這個(gè)模式的單詞只有cat和hat。還要注意以at開(kāi)頭的行也沒(méi)有
匹配礼预。字符組中必須有個(gè)字符來(lái)匹配相應(yīng)的位置眠砾。
在不太確定某個(gè)字符的大小寫(xiě)時(shí),字符組會(huì)非常有用托酸。
$ echo "Yes" | sed -n '/[Yy]es/p'
Yes
$ echo "yes" | sed -n '/[Yy]es/p'
yes
可以在單個(gè)表達(dá)式中用多個(gè)字符組褒颈。
$ echo "Yes" | sed -n '/[Yy][Ee][Ss]/p'
Yes
$ echo "yEs" | sed -n '/[Yy][Ee][Ss]/p'
yEs
$ echo "yeS" | sed -n '/[Yy][Ee][Ss]/p'
yeS
正則表達(dá)式使用了3個(gè)字符組來(lái)涵蓋了3個(gè)字符位置含有大小寫(xiě)的情況。
字符組不必只含有字母获高,也可以在其中使用數(shù)字哈肖。
$ cat data7
This line doesn't contain a number.
This line has 1 number on it.
This line a number 2 on it.
This line has a number 4 on it.
$ sed -n '/[0123]/p' data7
This line has 1 number on it.
This line a number 2 on it.
這個(gè)正則表達(dá)式模式匹配了任意含有數(shù)字0、 1念秧、 2或3的行淤井。含有其他數(shù)字以及不含有數(shù)字的行都會(huì)被忽略掉。
7摊趾、排除型字符組
$ cat data6
This is a test of a line.
The cat is sleeping.
That is a very nice hat.
This test is at line four.
at ten o'clock we'll go home.
$ sed -n '/[^ch]at/p' data6
This test is at line four.
通過(guò)排除型字符組币狠,正則表達(dá)式模式會(huì)匹配c或h之外的任何字符以及文本模式。由于空格字符屬于這個(gè)范圍砾层,它通過(guò)了模式匹配漩绵。但即使是排除,字符組仍然必須匹配一個(gè)字符肛炮,所以以at開(kāi)頭的行仍然未能匹配模式止吐。
8、區(qū)間
通過(guò)指定數(shù)字區(qū)間來(lái)簡(jiǎn)化郵編的例子侨糟。
$ sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p' data8
60633
46201
45902
這樣可是節(jié)省了不少的鍵盤(pán)輸入碍扔!每個(gè)字符組都會(huì)匹配0~9的任意數(shù)字。如果字母出現(xiàn)在數(shù)據(jù)中的任何位置秕重,這個(gè)模式都將不成立不同。
$ echo "a8392" | sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p'
$
$ echo "1839a" | sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p'
$
$ echo "18a92" | sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p'
同樣的方法也適用于字母。
$ sed -n '/[c-h]at/p' data6
The cat is sleeping.
That is a very nice hat.
新的模式[c-h]at匹配了首字母在字母c和字母h之間的單詞溶耘。這種情況下二拐,只含有單詞at的行將無(wú)法匹配該模式。
還可以在單個(gè)字符組指定多個(gè)不連續(xù)的區(qū)間凳兵。
$ sed -n '/[a-ch-m]at/p' data6
The cat is sleeping.
That is a very nice hat.
該字符組允許區(qū)間a~c百新、 hm中的字母出現(xiàn)在at文本前,但不允許出現(xiàn)dg的字母庐扫。434 第 20 章 正則表達(dá)式
$ echo "I'm getting too fat." | sed -n '/[a-ch-m]at/p'
該模式不匹配fat文本吟孙,因?yàn)樗鼪](méi)在指定的區(qū)間澜倦。
9、特殊的字符組
[[:alpha:]] 匹配任意字母字符杰妓,不管是大寫(xiě)還是小寫(xiě)
[[:alnum:]] 匹配任意字母數(shù)字字符0~9藻治、 A~Z或a~z
[[:blank:]] 匹配空格或制表符
[[:digit:]] 匹配0~9之間的數(shù)字
[[:lower:]] 匹配小寫(xiě)字母字符a~z
[[:print:]] 匹配任意可打印字符
[[:punct:]] 匹配標(biāo)點(diǎn)符號(hào)
[[:space:]] 匹配任意空白字符:空格、制表符巷挥、 NL桩卵、 FF、 VT和CR
[[:upper:]] 匹配任意大寫(xiě)字母字符A~Z
$ echo "abc" | sed -n '/[[:digit:]]/p'
$ echo "abc" | sed -n '/[[:alpha:]]/p'
abc
$ echo "abc123" | sed -n '/[[:digit:]]/p'
abc123
$ echo "This is, a test" | sed -n '/[[:punct:]]/p'
This is, a test
$ echo "This is a test" | sed -n '/[[:punct:]]/p'
10倍宾、星號(hào)
在字符后面放置星號(hào)表明該字符必須在匹配模式的文本中出現(xiàn)0次或多次雏节。
$ echo "ik" | sed -n '/ie*k/p'
ik
$ echo "iek" | sed -n '/ie*k/p'
iek
$ echo "ieek" | sed -n '/ie*k/p'
ieek
$ echo "ieeek" | sed -n '/ie*k/p'20.2 定義 BRE 模式 435
ieeek
$ echo "ieeeek" | sed -n '/ie*k/p'
ieeeek
11、問(wèn)號(hào)
問(wèn)號(hào)類(lèi)似于星號(hào)高职,不過(guò)有點(diǎn)細(xì)微的不同钩乍。問(wèn)號(hào)表明前面的字符可以出現(xiàn)0次或1次,但只限于此怔锌。它不會(huì)匹配多次出現(xiàn)的字符寥粹。
$ echo "bt" | gawk '/be?t/{print $0}'
bt
$ echo "bet" | gawk '/be?t/{print $0}'
bet
$ echo "beet" | gawk '/be?t/{print $0}'
$ echo "beeet" | gawk '/be?t/{print $0}'
12、加號(hào)
加號(hào)是類(lèi)似于星號(hào)的另一個(gè)模式符號(hào)埃元,但跟問(wèn)號(hào)也有不同涝涤。加號(hào)表明前面的字符可以出現(xiàn)1次或多次,但必須至少出現(xiàn)1次岛杀。如果該字符沒(méi)有出現(xiàn)阔拳,那么模式就不會(huì)匹配。
$ echo "beeet" | gawk '/be+t/{print $0}'
beeet
$ echo "beet" | gawk '/be+t/{print $0}'
beet
$ echo "bet" | gawk '/be+t/{print $0}'
bet
$ echo "bt" | gawk '/be+t/{print $0}'
如果字符e沒(méi)有出現(xiàn)类嗤,模式匹配就不成立糊肠。加號(hào)同樣適用于字符組,與星號(hào)和問(wèn)號(hào)的使用方式相同遗锣。
$ echo "bt" | gawk '/b[ae]+t/{print $0}'
$
$ echo "bat" | gawk '/b[ae]+t/{print $0}'
bat
$ echo "bet" | gawk '/b[ae]+t/{print $0}'
bet
$ echo "beat" | gawk '/b[ae]+t/{print $0}'
beat
$ echo "beet" | gawk '/b[ae]+t/{print $0}'
beet
$ echo "beeat" | gawk '/b[ae]+t/{print $0}'
beeat
這次如果字符組中定義的任一字符出現(xiàn)了货裹,文本就會(huì)匹配指定的模式。
13黄伊、使用花括號(hào)
這里有個(gè)使用簡(jiǎn)單的單值間隔的例子。
$ echo "bt" | gawk --re-interval '/be{1}t/{print $0}'
$438 第 20 章 正則表達(dá)式
$ echo "bet" | gawk --re-interval '/be{1}t/{print $0}'
bet
$ echo "beet" | gawk --re-interval '/be{1}t/{print $0}'
通過(guò)指定間隔為1派殷,限定了該字符在匹配模式的字符串中出現(xiàn)的次數(shù)还最。如果該字符出現(xiàn)多次,模式匹配就不成立毡惜。很多時(shí)候拓轻,同時(shí)指定下限和上限也很方便。
$ echo "bt" | gawk --re-interval '/be{1,2}t/{print $0}'
$
$ echo "bet" | gawk --re-interval '/be{1,2}t/{print $0}'
bet
$ echo "beet" | gawk --re-interval '/be{1,2}t/{print $0}'
beet
$ echo "beeet" | gawk --re-interval '/be{1,2}t/{print $0}'
在這個(gè)例子中经伙,字符e可以出現(xiàn)1次或2次扶叉,這樣模式就能匹配勿锅;否則,模式無(wú)法匹配枣氧。
間隔模式匹配同樣適用于字符組溢十。
$ echo "bt" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
$
$ echo "bat" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
bat
$ echo "bet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
bet
$ echo "beat" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
beat
$ echo "beet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
beet
$ echo "beeat" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
$
$ echo "baeet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
$
$ echo "baeaet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
如果字母a或e在文本模式中只出現(xiàn)了1~2次,則正則表達(dá)式模式匹配达吞;否則张弛,模式匹配失敗。
14酪劫、管道符號(hào)
管道符號(hào)允許你在檢查數(shù)據(jù)流時(shí)吞鸭,用邏輯OR方式指定正則表達(dá)式引擎要用的兩個(gè)或多個(gè)模式。如果任何一個(gè)模式匹配了數(shù)據(jù)流文本覆糟,文本就通過(guò)測(cè)試刻剥。如果沒(méi)有模式匹配,則數(shù)據(jù)流文本匹配失敗滩字。
使用管道符號(hào)的格式如下:
expr1|expr2|...
這里有個(gè)例子造虏。
$ echo "The cat is asleep" | gawk '/cat|dog/{print $0}'20.4 正則表達(dá)式實(shí)戰(zhàn) 439
The cat is asleep
$ echo "The dog is asleep" | gawk '/cat|dog/{print $0}'
The dog is asleep
$ echo "The sheep is asleep" | gawk '/cat|dog/{print $0}'
這個(gè)例子會(huì)在數(shù)據(jù)流中查找正則表達(dá)式cat或dog。正則表達(dá)式和管道符號(hào)之間不能有空格踢械,否則它們也會(huì)被認(rèn)為是正則表達(dá)式模式的一部分酗电。管道符號(hào)兩側(cè)的正則表達(dá)式可以采用任何正則表達(dá)式模式(包括字符組)來(lái)定義文本。
$ echo "He has a hat." | gawk '/[ch]at|dog/{print $0}'
He has a hat.
這個(gè)例子會(huì)匹配數(shù)據(jù)流文本中的cat内列、 hat或dog撵术。\
15、表達(dá)式分組
正則表達(dá)式模式也可以用圓括號(hào)進(jìn)行分組话瞧。當(dāng)你將正則表達(dá)式模式分組時(shí)嫩与,該組會(huì)被視為一
個(gè)標(biāo)準(zhǔn)字符〗慌牛可以像對(duì)普通字符一樣給該組使用特殊字符划滋。舉個(gè)例子:
$ echo "Sat" | gawk '/Sat(urday)?/{print $0}'
Sat
$ echo "Saturday" | gawk '/Sat(urday)?/{print $0}'
Saturday
結(jié)尾的urday分組以及問(wèn)號(hào),使得模式能夠匹配完整的Saturday或縮寫(xiě)Sat埃篓。
將分組和管道符號(hào)一起使用來(lái)創(chuàng)建可能的模式匹配組是很常見(jiàn)的做法处坪。
$ echo "cat" | gawk '/(c|b)a(b|t)/{print $0}'
cat
$ echo "cab" | gawk '/(c|b)a(b|t)/{print $0}'
cab
$ echo "bat" | gawk '/(c|b)a(b|t)/{print $0}'
bat
$ echo "bab" | gawk '/(c|b)a(b|t)/{print $0}'
bab
$ echo "tab" | gawk '/(c|b)a(b|t)/{print $0}'
$
$ echo "tac" | gawk '/(c|b)a(b|t)/{print $0}'
模式(c|b)a(b|t)會(huì)匹配第一組中字母的任意組合以及第二組中字母的任意組合。