隨着對UNIX和LINUX熟悉程度的不斷加深,須要常常接觸到正則表達式這個領域。使用shell時,從一個文件中抽取多於一個字符串將會很麻煩。例如,在一個文本中抽取一個詞,它的頭兩個字符是大寫的,後面緊跟四個數字。若是不使用某種正則表達式,在shell中將不能實現這個操做。
本章內容包括:
•匹配行首與行尾。
•匹配數據集。
•只匹配字母和數字。
•匹配必定範圍內的字符串集。
當從一個文件或命令輸出中抽取或過濾文本時,可使用正則表達式(RE),正則表達式
是一些特殊或不很特殊的字符串模式的集合。
爲了抽取或得到信息,咱們給出抽取操做應遵照的一些規則。這些規則由一些特殊字符
或進行模式匹配操做時使用的元字符組成。也可使用規則字符做爲模式中的一部分進行搜
尋。例如,A將查詢A,x將查找字母x。
系統自帶的全部大的文本過濾工具在某種模式下都支持正則表達式的使用,而且還包括
一些擴展的元字符集。這裏只涉及其中之一,即以字符出現狀況進行匹配的表達式,緣由是
一些系統將這類模式劃分爲一組造成基本元字符的集合。這是一個好想法,本書也採用這種
方式。
本章設計的基本元字符使用在grep和sed命令中,同時結合{\\}(以字符出現狀況進行匹配
的元字符)使用在awk語言中。
表7-1基本元字符集及其含義
^ 只匹配行首
$ 只匹配行尾
* 一個單字符後緊跟*,匹配0個或多個此單字符
[] 匹配[]內字符。能夠是一個單字符,也能夠是字符序列。可使用-
表示[]內字符序列範圍,如用[1-5]代替[12345]
\ 用來屏蔽一個元字符的特殊含義。由於有時在shell中一些元字符有
特殊含義。\可使其失去應有意義
. 只匹配任意單字符
pattern\{n\} 只用來匹配前面pattern出現次數。n爲次數
pattern\{n,\}m 只含義同上,但次數最少爲n
pattern\{n,m\} 只含義同上,但pattern出現次數在n與m之間
如今詳細講解其中特殊含義。
使用句點匹配單字符
句點"."能夠匹配任意單字符。例如,若是要匹配一個字符串,以beg開頭,中間夾一個任意字符,那麼能夠表示爲beg.n,"."能夠匹配字符串頭,也能夠是中間任意字符。
在ls -l命令中,能夠匹配必定權限:
...x..x..x
此格式匹配用戶自己,用戶組及其餘組成員的執行權限。
假定正在過濾一個文本文件,對於一個有10個字符的腳本集,要求前4個字符以後爲XC,
匹配操做以下:
....XC....
以上例子解釋爲前4個字符任意,5,6字符爲XC,後4個字符也任意。
注意,"."容許匹配ASCII集中任意字符,或爲字母,或爲數字。
在行首以^匹配字符串或字符序列
^容許在一行的開始匹配字符或單詞。例如,使用ls -l命令,並匹配目錄。之因此能夠
這樣作是由於ls -l命令結果每行第一個字符是d,即表明一個目錄。
回到腳本(1),使用^001,結果將匹配每行開始爲001的字符串或單詞:
能夠將各類模式結合使用,例如:
^...4XC....
以上模式表示,在每行開始,匹配任意3個字符,後跟4XC,最後爲任意4個字符。^在正
則表達式中使用頻繁,由於大量的抽取操做一般在行首。
在行首第4個字符爲1,匹配操做表示爲:
^...1
結果爲:
行首前4個字符爲comp,匹配操做表示爲:
^comp
假定從新定義匹配模式,行首前4個字符爲comp,後面緊跟兩個任意字符,並以ing結尾,
一種方法爲:
^comp..ing
以上例子太明顯了,不是頗有用,但仍講述了混合使用正則模式的基本概念。
在行尾以$匹配字符串或字符
能夠說$與^正相反,它在行尾匹配字符串或字符,$符號放在匹配單詞後。假定要匹配以
單詞trouble結尾的全部行,操做爲:
trouble$
相似的,使用1d$返回每行以1d結尾的全部字符串。
若是要匹配全部空行,執行如下操做:
^$
具體分析爲匹配行首,又匹配行尾,中間沒有任何模式,所以爲空行。
若是隻返回包含一個字符的行,操做以下:
^.$
不像空白行,在行首與行尾之間有一個模式,表明任意單字符。
若是在行尾匹配單詞jet01,操做以下:
jet01$
使用*匹配字符串中的單字符或其重複序列
使用此特殊字符匹配任意字符或字符串的重複屢次表達式。例如:
compu*t
將匹配字符u一次或屢次
使用\屏蔽一個特殊字符的含義
有時須要查找一些字符或字符串,而它們包含了系統指定爲特殊字符的一個字符。什麼是特殊字符?通常意義上講,下列字符能夠認爲是特殊字符:
假定要匹配包含字符"."的各行而"."表明匹配任意單字符的特殊字符,所以須要屏蔽其含義。操做以下:
\.
上述模式不認爲反斜槓後面的字符是特殊字符,而是一個普通字符,即句點。
假定要匹配包含^的各行,將反斜槓放在它前面就能夠屏蔽其特殊含義。以下:
\^
若是要在正則表達式中匹配以*.pas結尾的全部文件,可作以下操做:
\*\.pas
便可屏蔽字符*的特定含義。
使用[]匹配一個範圍或集合
使用[]匹配特定字符串或字符串集,能夠用逗號將括弧內要匹配的不一樣字符串分開,但並不強制要求這樣作(一些系統提倡在複雜的表達式中使用逗號),這樣作能夠增長模式的可讀性。
使用"-"表示一個字符串範圍,代表字符串範圍從"-"左邊字符開始,到"-"右邊字符結束。
若是熟知一個字符串匹配操做,應常用[]模式。
假定要匹配任意一個數字,可使用:
[0123456789]
然而,經過使用"-"符號能夠簡化操做:
[0-9]
或任意小寫字母
[a-z]
要匹配任意字母,則使用:
[A-Za-z]
代表從A-Z、a-z的字母範圍。
如要匹配任意字母或數字,模式以下:
[A-Za-z0-9]
在字符序列結合使用中,能夠用[]指出字符範圍。假定要匹配一單詞,以s開頭,中間有
一任意字母,以t結尾,那麼操做以下:
s[a-zA-Z]t
上述過程返回大寫或小寫字母混合的單詞,如僅匹配小寫字母,可以使用:
s[a-z]t
如要匹配Computer或computer兩個單詞,可作以下操做:
[Cc]omputer
爲抽取諸如Scout、shout、bought等單詞,使用下列表達式:
[ou].*t
匹配以字母o或u開頭,後跟任意一個字符任意次,並以t結尾的任意字母。
也許要匹配全部包含system後跟句點的全部單詞,這裏S可大寫或小寫。使用以下操做:
[Ss]ystem\.
[]在指定模式匹配的範圍或限制方面頗有用。結合使用*與[]更是有益,例如[A-Za-Z]*將
匹配全部單詞。
[A-Za-z]*
注意^符號的使用,當直接用在第一個括號裏,意指否認或不匹配括號裏內容。
[^a-zA-Z]
匹配任一非字母型字符,而
[^0-9]
匹配任一非數字型字符。
經過最後一個例子,應可猜知除了使用^,還有一些方法用來搜索任意一個特殊字符。
使用\{\}匹配模式結果出現的次數
使用*可匹配全部匹配結果任意次,但若是隻要指定次數,就應使用\{\},此模式有三種
形式,即:
pattern\{n\} 匹配模式出現n次。
pattern\{n,\} 匹配模式出現最少n次。
pattern\{n,m} 匹配模式出現n到m次之間,n,m爲0-255中任意整數。
請看第一個例子,匹配字母A出現兩次,並以B結尾,操做以下:
A\{2\}B
匹配值爲AAB
匹配A至少4次,使用:
A\{4,\}B
能夠得結果AAAAB或AAAAAAAB,但不能爲AAAB。
如給出出現次數範圍,例如A出現2次到4次之間:
A\{2,4\}B
則結果爲AAB、AAAB、AAAAB,而不是AB或AAAAAB等。
假定從下述列表中抽取代碼:
格式以下:前4個字符是數字,接下來是xx,最後4個也是數字,操做以下:
[0-9]\{4\}XX[0-9]\{4\}
具體含義以下:
1)匹配數字出現4次。
2)後跟代碼xx。
3)最後是數字出現4次。
在寫正則表達式時,可能會有點難度或達不到預期效果,一個好習慣是在寫真正的正則表達式前先寫下預期的輸出結果。這樣作,當寫錯時,能夠逐漸修改,以消除意外結果,直至返回正確值。爲節省設計基本模式的時間,表7-2給出一些例子,這些例子並沒有特別順序。
表7-2常用的正則表達式舉例
--------------------------------------------------------------------------
^ 行首
$ 行尾
^[the] 以the開頭行
[Ss]igna[lL] 匹配單詞signal、signaL、Signal、SignaL
[Ss]igna[lL]\. 同上,但加一句點
[mayMAY] 包含may大寫或小寫字母的行
^USER$ 只包含USER的行
[tty]$ 以tty結尾的行
\. 帶句點的行
^d..x..x..x 對用戶、用戶組及其餘用戶組成員有可執行權限的目錄
^[^l] 排除關聯目錄的目錄列表
[.*0] 0以前或以後加任意字符
[000*] 000或更多個
[iI] 大寫或小寫I
[iI][nN] 大寫或小寫i或n
[^$] 空行
[^.*$] 匹配行中任意字符串,匹配任意行
^......$ 包括6個字符的行
[a-zA-Z] 任意單字符
[a-z][a-z]* 至少一個小寫字母
[^0-9\$] 非數字或美圓標識
[^0-0A-Za-z] 非數字或字母
[123] 1到3中一個數字
[Dd]evice 單詞device或Device
De..ce 前兩個字母爲De,後跟兩個任意字符,最後爲ce
\^q 以^q開始行
^.$ 僅有一個字符的行
^\.[0-9][0-9] 以一個句點和兩個數字開始的行
'"Device"' 單詞device
De[Vv]ice\. 單詞Device或device
[0-9]\{2\}-[0-9]\{2\}-[0-9]\{4\} 日期格式dd-mm-yyyy
[0-9]\{3\}\.[0-9]\{3\}\.[0-9]\{3\}\.[0-9]\{3\} IP地址格式nnn.nnn.nnn.nnn
小結
在shell編程中,一段好的腳本與完美的腳本間的差異之一,就是要熟知正則表達式並學會使用它們。相比較起來,用一個命令抽取一段文本比用三四個命令得出一樣的結果要節省許多時間。
正則表達式