《Linux命令行與shell腳本編程大全》乓旗,4 E -- Chapter 20
一、 什么是正則表達(dá)式
1. 定義
- 正則表達(dá)式是你所定義的模式模板(pattern template)集索,Linux工具可以用它來過濾文本屿愚。Linux工具(比如sed編輯器或gawk程序)能夠在處理數(shù)據(jù)時使用正則表達(dá)式對數(shù)據(jù)進(jìn)行模式匹配。如果數(shù)據(jù)匹配模式务荆,它就會被接受并進(jìn)一步處理妆距;如果數(shù)據(jù)不匹配模式,它就會被濾掉蛹含。圖20-1描述了這個過程毅厚。
- 正則表達(dá)式模式利用通配符來描述數(shù)據(jù)流中的一個或多個字符。Linux中有很多場景都可以使用通配符來描述不確定的數(shù)據(jù)浦箱。你已經(jīng)看到過在Linux的 ls 命令中使用通配符列出文件和目錄的例子(參見第3章)吸耿。星號通配符允許你只列出滿足特定條件的文件,例如:
$ ls -al da*
-rw-r--r-- 1 rich rich 45 Nov 26 12:42 data
-rw-r--r-- 1 rich rich 25 Dec 4 12:40 data.tst
-rw-r--r-- 1 rich rich 180 Nov 26 12:42 data1
-rw-r--r-- 1 rich rich 45 Nov 26 12:44 data2
-rw-r--r-- 1 rich rich 73 Nov 27 12:31 data3
-rw-r--r-- 1 rich rich 79 Nov 28 14:01 data4
-rw-r--r-- 1 rich rich 187 Dec 4 09:45 datatest
-
da*
參數(shù)會讓ls
命令只列出名字以da
開頭的文件酷窥。文件名中da之后可以有任意多個字 符(包括什么也沒有)咽安,ls
命令會讀取目錄中所有文件的信息,但只顯示跟通配符匹配的文件的信息蓬推。正則表達(dá)式通配符模式的工作原理與之類似妆棒。正則表達(dá)式模式含有文本或特殊字符,為sed編輯器和gawk程序定義了一個匹配數(shù)據(jù)時采用的模板「馍海可以在正則表達(dá)式中使用不同的特殊字符來定義特定的數(shù)據(jù)過濾模式动分。
2. 正則表達(dá)式的類型
- 使用正則表達(dá)式最大的問題在于有不止一種類型的正則表達(dá)式。Linux中的不同應(yīng)用程序可能會用不同類型的正則表達(dá)式红选。這其中包括編程語言(Java澜公、Perl和Python)、Linux實用工具(比如sed編輯器喇肋、gawk程序和grep工具)以及主流應(yīng)用(比如MySQL和PostgreSQL數(shù)據(jù)庫服務(wù)器)坟乾。
- 正則表達(dá)式是通過正則表達(dá)式引擎(regular expression engine)實現(xiàn)的。正則表達(dá)式引擎是一套底層軟件蝶防,負(fù)責(zé)解釋正則表達(dá)式模式并使用這些模式進(jìn)行文本匹配甚侣。在Linux中,有兩種流行的正則表達(dá)式引擎:
- POSIX基礎(chǔ)正則表達(dá)式(basic regular expression间学,BRE)引擎
- POSIX擴(kuò)展正則表達(dá)式(extended regular expression殷费,ERE)引擎
- 由于實現(xiàn)正則表達(dá)式的方法太多,很難用一個簡潔的描述來涵蓋所有可能的正則表達(dá)式低葫。
二宗兼、 定義 BRE 模式
- 最基本的BRE模式是匹配數(shù)據(jù)流中的文本字符。本節(jié)將會演示如何在正則表達(dá)式中定義文本
以及會得到什么樣的結(jié)果氮采。
1. 純文本
- 第18章演示了如何在sed編輯器和gawk程序中用標(biāo)準(zhǔn)文本字符串來過濾數(shù)據(jù)。通過下面的例
子來復(fù)習(xí)一下染苛。
$ 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}
- 第一個模式定義了一個單詞test鹊漠。sed編輯器和gawk程序腳本用它們各自的 print 命令打印出匹配該正則表達(dá)式模式的所有行。由于 echo 語句在文本字符串中包含了單詞test茶行,數(shù)據(jù)流文本能夠匹配所定義的正則表達(dá)式模式躯概,因此sed編輯器顯示了該行。
- 第二個模式也定義了一個單詞畔师,這次是trial娶靡。因為 echo 語句文本字符串沒包含該單詞,所以正則表達(dá)式模式?jīng)]有匹配看锉,因此sed編輯器和gawk程序都沒打印該行姿锭。
- 正則表達(dá)式并不關(guān)心模式在數(shù)據(jù)流中的位置。它也不關(guān)心模式出現(xiàn)了多少次伯铣。一旦正則表達(dá)式匹配了文本字符串中任意位置上的模式呻此,它就會將該字符串傳回Linux工具。關(guān)鍵在于將正則表達(dá)式模式匹配到數(shù)據(jù)流文本上腔寡。
- 重要的是記住正則表達(dá)式對匹配的模式非常挑剔焚鲜。第一條原則就是:正則表達(dá)式模式都區(qū)分大小寫。這意味著它們只會匹配大小寫也相符的模式。
$ echo "This is a test" | sed -n '/this/p'
$ echo "This is a test" | sed -n '/This/p'
This is a test
- 在正則表達(dá)式中忿磅,你不用寫出整個單詞糯彬。只要定義的文本出現(xiàn)在數(shù)據(jù)流中,正則表達(dá)式就能夠匹配葱她。
$ echo "The books are expensive" | sed -n '/book/p'
The books are expensive
-
不用局限于在正則表達(dá)式中只用單個文本單詞撩扒,可以在正則表達(dá)式中使用空格和數(shù)字
單詞間有兩個空格的行匹配正則表達(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.
2. 特殊字符
在正則表達(dá)式中定義文本字符時却舀,有一些特例。有些字符在正則表達(dá)式中有特別的含義锤灿。如果要在文本模式中使用這些字符挽拔,結(jié)果會超出你的意料。
-
正則表達(dá)式識別的特殊字符包括:
·.*[]^${}\+?|(
不能在文本模式中單獨使用這些字符但校,如果要用某個特殊字符作為文本字符螃诅,就必須轉(zhuǎn)義符號反斜線(\)。轉(zhuǎn)義字符來告訴正則表達(dá)式引擎應(yīng)該將接下來的字符當(dāng)作普通的文本字符状囱。
如果要查找文本中的美元符术裸,只要在它前面加個反斜線袭艺。
$ cat data2
The cost is $4.00
$ sed -n '/\$/p' data2
The cost is $4.00
- 由于反斜線是特殊字符,如果要在正則表達(dá)式模式中使用它猾编,你必須對其轉(zhuǎn)義,這樣就產(chǎn)生
了兩個反斜線答倡。
$ echo "\ is a special character" | sed -n '/\\\/p'
\ is a special character
- 盡管正斜線不是正則表達(dá)式的特殊字符驴党,但如果它出現(xiàn)在sed編輯器或gawk程序的正則表達(dá)式中,你就會得到一個錯誤港庄。要使用正斜線倔既,也需要進(jìn)行轉(zhuǎn)義。
$ echo "3 / 2" | sed -n '///p'
sed: -e expression #1, char 3: unknown command: `/'
$ echo "3 / 2" | sed -n '/\//p'
3 / 2
3. 錨字符
- 默認(rèn)情況下攘轩,當(dāng)指定一個正則表達(dá)式模式時叉存,只要模式出現(xiàn)在數(shù)據(jù)流中的任何地方,它就能匹配度帮。有兩個特殊字符可以用來將模式鎖定在數(shù)據(jù)流中的行首或行尾歼捏。
3.1 鎖定在行首
- 脫字符(^)定義從數(shù)據(jù)流中文本行的行首開始的模式稿存。如果模式出現(xiàn)在行首之外的位置,正則表達(dá)式模式則無法匹配瞳秽。
$ echo "The book store" | sed -n '/^ book/p'
$ echo "Books are great" | sed -n '/^ Book/p'
Books are great
- 脫字符會在每個由換行符決定的新數(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.
- 如果你將脫字符放到模式開頭之外的其他位置,那么它就跟普通字符一樣练俐,不再是特殊字符了:
$ echo "This ^ is a test" | sed -n '/s ^ /p'
This ^ is a test
說明 :如果指定正則表達(dá)式模式時只用了脫字符袖迎,就不需要用反斜線來轉(zhuǎn)義。但如果你在模式中先指定了脫字符腺晾,隨后還有其他一些文本燕锥,那么你必須在脫字符前用轉(zhuǎn)義字符。
3.2 鎖定在行尾
- 跟在行首查找模式相反的就是在行尾查找悯蝉。特殊字符美元符($)定義了行尾錨點归形。將這個特殊字符放在文本模式之后來指明數(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'
3.3 組合錨點
? 一些常見情況下鼻由,可以在同一行中將行首錨點和行尾錨點組合在一起使用暇榴。
-
^模式$
,查找只含有特定文本模式的數(shù)據(jù)行蕉世。
cat data4
this is a test of using both anchors
I said this is a test
this is a test
I'm sure this is a test.
$ sed -n '/^this is a test$/p' data4
this is a test
-
^$
蔼紧,將兩個錨點直接組合在一起,之間不加任何文本狠轻,這樣過濾出數(shù)據(jù)流中的空白行
$ cat data5
This is one test line.
This is one test line.
This is another test line.
sed '/^ $/d' data5
This is one test line.
This is another test line.
? 定義的正則表達(dá)式模式會查找行首和行尾之間什么都沒有的那些行奸例。由于空白行在兩個換行符之間沒有文本向楼,剛好匹配了正則表達(dá)式模式。sed編輯器用刪除命令 d 來刪除匹配該正則表達(dá)式模式的行,因此刪除了文本中的所有空白行重荠。這是從文檔中刪除空白行的有效方法虚茶。
3.4 點號字符
- 特殊字符點號用來匹配除換行符之外的任意單個字符。它必須匹配一個字符婆殿,如果在點號字符的位置沒有字符婆芦,那么模式就不成立。
$ 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.
? 行有點復(fù)雜消约。注意或粮,我們匹配了 at ,但在 at 前面并沒有任何字符來匹配點號字符渣锦。其實是有的袋毙!在正則表達(dá)式中娄猫,空格也是字符媳溺,因此 at 前面的空格剛好匹配了該模式悬蔽。第五行證明了這點捉兴,將 at 放在行首就不會匹配該模式了倍啥。
3.4 字符組
- 點號特殊字符在匹配某個字符位置上的任意字符時很有用始藕。但如果你想要限定待匹配的具體字符呢氮趋?在正則表達(dá)式中剩胁,這稱為字符組(character class)昵观。可以定義用來匹配文本模式中某個位置的一組字符扩借。如果字符組中的任意一個字符出現(xiàn)在了數(shù)據(jù)流中潮罪,那它就匹配了該模式领斥。
- 使用方括號來定義一個字符組何恶。方括號中包含所有你希望出現(xiàn)在該字符組中的字符细层。然后你可以在模式中使用整個組疫赎,就跟使用其他通配符一樣捧搞。這需要一點時間來適應(yīng)胎撇,但一旦你適應(yīng)了晚树,效果可是令人驚嘆的题涨。
下面是個創(chuàng)建字符組的例子。
$ 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
The cat is sleeping.
That is a very nice hat.
? 首先篩選出了含有at的行闰渔,但不包含at ten o'clock we'll go home.
這一行冈涧,因為這一行的at前面沒有字符,而該模式規(guī)定除了匹配at字符之外营曼,還要匹配s字符或h字符蒂阱,因此at ten o'clock we'll go home.
淘汰录煤,The cat is sleeping.
和That is a very nice hat.
通過妈踊。
- 在不太確定某個字符的大小寫時廊营,字符組會非常有用露筒。
$ echo "Yes" | sed -n '/[Yy]es/p'
Yes
$ echo "yes" | sed -n '/[Yy]es/p'
yes
- 也可以在單個表達(dá)式中用多個字符組邀窃。
$ 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
- 在不太確定某個字符的大小寫時,字符組會非常有用肪虎。
$ echo "Yes" | sed -n '/[Yy]es/p'
Yes
$ echo "yes" | sed -n '/[Yy]es/p'
yes
- 字符組不必只含有字母扇救,也可以在其中使用數(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.
? 這個正則表達(dá)式模式匹配了任意含有數(shù)字0、1锌雀、2或3的行。含有其他數(shù)字以及不含有數(shù)字的行都會被忽略掉婿牍。
-
可以將字符組組合在一起等脂,以檢查數(shù)字是否具備正確的格式。
比如我們的郵編是六位的數(shù)字锨并,那么下面的命令就可以把不是六位的給篩選掉`
$ cat data8
60633
46201
223001
4353
22203
$ sed -n '/^[0123456789][0123456789][0123456789][0123456789][0123456789]$/p' data8
60633
46201
22203
- 字符組的一個極其常見的用法是解析拼錯的單詞第煮,比如用戶表單輸入的數(shù)據(jù)包警√芈粒可以創(chuàng)建正則表達(dá)式來接受數(shù)據(jù)中常見的拼寫錯誤鲫剿。
$ cat data9
I need to have some maintenence done on my car.
I'll pay that in a seperate invoice.
After I pay for the maintenance my car will be as good as new.
#換行能不能代替為空格?
$ sed -n '/maint[ea]n[ae]nce/p/sep[ea]r[ea]te/p' data9
I need to have some maintenence done on my car.
I'll pay that in a seperate invoice.
After I pay for the maintenance my car will be as good as new.
? 兩個 sed 打印命令利用正則表達(dá)式字符組來幫助找到文本中拼錯的單詞maintenance和separate政冻。同樣的,正則表達(dá)式模式也能匹配正確拼寫的maintenance李丰。
3.5 排除型字符組
- 在正則表達(dá)式模式中逆屡,也可以反轉(zhuǎn)字符組的作用≥褐危可以尋找組中沒有的字符谣旁,而不是去尋找組中含有的字符榄审。要這么做的話,只要在字符組的開頭加個脫字符杆麸。
$ 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.
This test is at line four.
$ sed -n '/[^ ch]at/p' data6
? 首先篩選出含有at的行搁进,之后在這些行必須還要滿足條件:at的前面沒有(空格)或
c
或h
,所以三者均被排除昔头。
3.5 區(qū)間
? 之前演示郵編的例子的時候饼问,必須在每個字符組中列出所有可能的數(shù)字,這實在有點麻煩揭斧。好在有一種便捷的方法可以讓人免受這番勞苦莱革。可以用單破折線符號在字符組中表示字符區(qū)間盅视。只需要指定區(qū)間的第一個字符單破折線以及區(qū)間的最后一個字符就行了纸型。
- 根據(jù)Linux系統(tǒng)采用的字符集(參見第2章),正則表達(dá)式會包括此區(qū)間內(nèi)的任意字符。現(xiàn)在你可以通過指定數(shù)字區(qū)間來簡化郵編的例子。
$ sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p' data8
60633
46201
45902
- 同樣的方法也適用于字母。
$ sed -n '/[c-h]at/p' data6
The cat is sleeping.
That is a very nice hat.
? 新的模式 [c-h]at 匹配了首字母在字母c和字母h之間的單詞。這種情況下,只含有單詞 at的行將無法匹配該模式。
- 還可以在單個字符組指定多個不連續(xù)的區(qū)間。
$ sed -n '/[a-ch-m]at/p' data6
The cat is sleeping.
That is a very nice hat.
? 該字符組允許區(qū)間ac、hm中的字母出現(xiàn)在 at 文本前,但不允許出現(xiàn)d~g的字母。
$ echo "I'm getting too fat." | sed -n '/[a-ch-m]at/p'
? 該模式不匹配 fat 文本,因為它沒在指定的區(qū)間迅涮。
3.6 特殊的字符組
- 除了定義自己的字符組外,BRE還包含了一些特殊的字符組,可用來匹配特定類型的字符。
-
表20-1介紹了可用的BRE特殊的字符組闰围。
- 可以在正則表達(dá)式模式中將特殊字符組像普通字符組一樣使用校仑。
$ 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'
- 使用特殊字符組可以很方便地定義區(qū)間泰佳∏穑可以用
[[:digit:]]
來代替區(qū)間[0-9]积仗。
3.7 星號
- 在字符后面放置星號表明該字符必須在匹配模式的文本中出現(xiàn)0次或多次漱挚,即可出現(xiàn)可不出現(xiàn)白华。
$ 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'
ieeek
- 這個模式符號廣泛用于處理有常見拼寫錯誤或在不同語言中有拼寫變化的單詞。舉個例子奇钞,如果需要寫個可能用在美式或英式英語中的腳本,可以這么寫:
$ echo "I'm getting a color TV" | sed -n '/colou*r/p'
I'm getting a color TV
$ echo "I'm getting a colour TV" | sed -n '/colou*r/p'
I'm getting a colour TV
? 模式中的 u* 表明字母u可能出現(xiàn)或不出現(xiàn)在匹配模式的文本中。
- 類似地,如果你知道一個單詞經(jīng)常被拼錯,你可以用星號來允許這種錯誤。
$ echo "I ate a potatoe with my lunch." | sed -n '/potatoe*/p'
I ate a potatoe with my lunch.
echo "I ate a potato with my lunch." | sed -n '/potatoe*/p'
I ate a potato with my lunch.
? 在可能出現(xiàn)的額外字母后面放個星號將允許接受拼錯的單詞是辕。
- 另一個方便的特性是將點號特殊字符和星號特殊字符組合起來锨苏。這個組合能夠匹配任意數(shù)量的任意字符松逊。它通常用在數(shù)據(jù)流中兩個可能相鄰或不相鄰的文本字符串之間犀暑。
$ echo "this is a regular pattern expression" | sed -n '/regular.*expression/p'
this is a regular pattern expression
? 可以使用這個模式輕松查找可能出現(xiàn)在數(shù)據(jù)流中文本行內(nèi)任意位置的多個單詞徊都。
- 星號還能用在字符組上择吊。它允許指定可能在文本中出現(xiàn)多次的字符組或字符區(qū)間囱持。
$ echo "bt" | sed -n '/b[ae]*t/p'
bt
$ echo "bat" | sed -n '/b[ae]*t/p'
bat
$ echo "bet" | sed -n '/b[ae]*t/p'
bet
$ echo "btt" | sed -n '/b[ae]*t/p'
btt
$ echo "baat" | sed -n '/b[ae]*t/p'
baat
$ echo "baaeeet" | sed -n '/b[ae]*t/p'
baaeeet
$ echo "baeeaeeat" | sed -n '/b[ae]*t/p'
baeeaeeat
$ echo "baakeeet" | sed -n '/b[ae]*t/p'
? 只要a和e字符以任何組合形式出現(xiàn)在 b 和 t 字符之間(就算完全不出現(xiàn)也行),模式就能夠匹配注整。如果出現(xiàn)了字符組之外的字符优俘,該模式匹配就會不成立换吧。
三折晦、擴(kuò)展正則表達(dá)式
? POSIX ERE模式包括了一些可供Linux應(yīng)用和工具使用的額外符號。gawk程序能夠識別ERE模式沾瓦,但sed編輯器不能筋遭。
警告:sed編輯器和gawk程序的正則表達(dá)式引擎之間是有區(qū)別的。gawk程序可以使用大多數(shù)擴(kuò)展正則表達(dá)式模式符號暴拄,并且能提供一些額外過濾功能漓滔,而這些功能都是sed編輯器所不具備的。但正因為如此乖篷,gawk程序在處理數(shù)據(jù)流時通常才比較慢响驴。
? 本節(jié)將介紹可用在gawk程序腳本中的較常見的ERE模式符號。
1. 問號
- 問號類似于星號撕蔼,不過有點細(xì)微的不同豁鲤。問號表明前面的字符可以出現(xiàn)0次或1次秽誊,但只限于此。它不會匹配多次出現(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}'
- 與星號一樣锅论,你可以將問號和字符組一起使用。
$ echo "bt" | gawk '/b[ae]?t/{print $0}'
bt
$ echo "bat" | gawk '/b[ae]?t/{print $0}'
bat
$ echo "bot" | gawk '/b[ae]?t/{print $0}'
$ echo "bet" | gawk '/b[ae]?t/{print $0}'
bet
$ echo "baet" | gawk '/b[ae]?t/{print $0}'
$ echo "beat" | gawk '/b[ae]?t/{print $0}'
$ echo "beet" | gawk '/b[ae]?t/{print $0}'
2. 加號
- 加號是類似于星號的另一個模式符號楣号,但跟問號也有不同最易。加號表明前面的字符可以出現(xiàn)1
次或多次,但必須至少出現(xiàn)1次炫狱。如果該字符沒有出現(xiàn)藻懒,那么模式就不會匹配。
#e至少要出現(xiàn)一次
$echo "bt" | gawk '/be+t/{print $0}'
$ echo "bet" | gawk '/be+t/{print $0}'
beeet
$ echo "beet" | gawk '/be+t/{print $0}'
beet
#如果字符組中定義的任一字符出現(xiàn)了视译,文本就會匹配指定的模式嬉荆。
$$ 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
3.使用花括號
-
ERE中的花括號允許你為可重復(fù)的正則表達(dá)式指定一個上限。這通常稱為間隔(interval)酷含”稍纾可以用兩種格式來指定區(qū)間。
- m :正則表達(dá)式準(zhǔn)確出現(xiàn) m 次椅亚。
- m, n :正則表達(dá)式至少出現(xiàn) m 次限番,至多 n 次。
這個特性可以精確調(diào)整字符或字符集在模式中具體出現(xiàn)的次數(shù)什往。
警告:默認(rèn)情況下,gawk程序不會識別正則表達(dá)式間隔慌闭。必須指定gawk程序的 --re- interval命令行選項才能識別正則表達(dá)式間隔别威。
- 這里有個使用簡單的單值間隔的例子。
$ echo "bt" | gawk --re-interval '/be{1}t/{print $0}'
$ echo "bet" | gawk --re-interval '/be{1}t/{print $0}'
bet
$ echo "beet" | gawk --re-interval '/be{1}t/{print $0}'
? 通過指定間隔為1驴剔,限定了該字符在匹配模式的字符串中出現(xiàn)的次數(shù)省古。如果該字符出現(xiàn)多次或不出現(xiàn),模式匹配就不成立丧失。
- 很多時候豺妓,同時指定下限和上限也很方便。
$ 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}'
? 字符 e 可以出現(xiàn)1次或2次布讹,這樣模式就能匹配琳拭;否則,模式無法匹配描验。
- 間隔模式匹配同樣適用于字符組白嘁。
$ 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}'
beeat
$ echo "baeet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
baeet
$ echo "baeaet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
baeaet
$ echo "baeaeat" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
?如果字母a或e在文本模式中只出現(xiàn)了1~2次,則正則表達(dá)式模式匹配膘流;否則絮缅,模式匹配失敗鲁沥。
4. 管道符號
-
管道符號允許你在檢查數(shù)據(jù)流時,用邏輯 OR 方式指定正則表達(dá)式引擎要用的兩個或多個模式耕魄。如果任何一個模式匹配了數(shù)據(jù)流文本画恰,文本就通過測試。如果沒有模式匹配吸奴,則數(shù)據(jù)流文本匹配失敗允扇。
使用管道符號的格式如下:expr1|expr2|...
這里有個例子。
$ echo "The cat is asleep" | gawk '/cat|dog/{print $0}'
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}'
這個例子會在數(shù)據(jù)流中查找正則表達(dá)式 cat 或 dog 奄抽。正則表達(dá)式和管道符號之間不能有空格蔼两,否則它們也會被認(rèn)為是正則表達(dá)式模式的一部分。
- 管道符號兩側(cè)的正則表達(dá)式可以采用任何正則表達(dá)式模式(包括字符組)來定義文本逞度。
$ echo "He has a hat." | gawk '/[ch]at|dog/{print $0}'
He has a hat.
5. 表達(dá)式分組
- 正則表達(dá)式模式也可以用圓括號進(jìn)行分組额划。當(dāng)你將正則表達(dá)式模式分組時,該組會被視為一個標(biāo)準(zhǔn)字符档泽】〈粒可以像對普通字符一樣給該組使用特殊字符。舉個例子:
$ echo "Sat" | gawk '/Sat(urday)?/{print $0}'
Sat
$ echo "Saturday" | gawk '/Sat(urday)?/{print $0}'
Saturday
? 結(jié)尾的 urday 分組以及問號馆匿,使得模式能夠匹配完整的 Saturday 或縮寫 Sat 抑胎。
- 將分組和管道符號一起使用來創(chuàng)建可能的模式匹配組是很常見的做法。
$ 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}'