1. 程式人生 > 其它 >Linux Shell指令碼之正則表示式

Linux Shell指令碼之正則表示式

正則表示式RE

重要的文字處理工具:vim sed awk grep

1.什麼是正則表示式?

正則表示式(regular expression,RE)是一種字元模式,用於在查詢過程中匹配指定的字元。

在大多數程式裡,正則表示式都被置於兩個斜槓之間;例如/l[oO]ve/就是由正斜槓界定的正則表示式。

它將匹配被查詢的行中任何位置出現的相同模式,在正則表示式中,元字元是重要的概念

匹配數字:1+$ ^:以xxx開頭,+前面的物件出現一個或多個,$是以xxx結尾,[]裡面的是匹配的模式

匹配mail:[a-z0-9_][email protected][a-z0-9]+\.[a-z]+
匹配ip:[
0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}
[[email protected] ~]# egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /etc/sysconfig/network-scripts/ifcfg-ens33
IPADDR=192.168.81.250
NETMASK=255.255.255.0
GATEWAY=192.168.81.2
DNS1
=192.168.81.2 或: [[email protected] ~]# egrep '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' /etc/sysconfig/network-scripts/ifcfg-ens33 IPADDR=192.168.81.250 NETMASK=255.255.255.0 GATEWAY=192.168.81.2 DNS1=192.168.81.2

2.元字元

定義:元字元是這樣一類字元,他們表達的是不同於字面本身的含義

shell元字元(也稱為萬用字元)由shell來解析,如rm -rf *.pdf,元字元星號*shell將其解析為任意多個字元

正則表示式元字元 由各種執行模式匹配操作的程式來解析,比如vim、grep、sed、awk、python

例子:

[[email protected] d09_shell_re_zzbds]# rm -rf *.ps		表示刪除所有以.ps結束的檔案
[[email protected] d09_shell_re_zzbds]# grep 'c*' /etc/passwd		這個不在是shell來解析,這一點會讓人誤以為是c開頭包含任意字元的行,其實不是,會輸出所有行,這裡由grep來解析,表示c出現0次或多次也就是c可以不出現,那麼不匹配c的行也會出現,顯然不是我們想要的,可以使用grep 'c\+' /etc/passwd來完成匹配或者egrep 'c+' /etc/passwd

vim例項:

:1,$ s/tom/TOM/g		這裡的1,$等同於%都表示全文假如有Tom字元或者tomorrow那麼也會被改變不太合理,可以使用正則
:1,$ s/\<[tT]om\>/TOM/g		這裡利用詞首和詞尾定位符鎖定只能是tom單詞才會被更改

2.1正則表示式元字元

=基於正則表示式元字元

匹配模式中嚴格區分大小寫

  元字元 							功能        								示例      

	^		行首定位符				grep '^root' /etc/passwd /etc/shadow

	$		行尾定位符     			grep 'bash$' /etc/passwd /etc/shadow

	.  		匹配單個字元    			grep 'r.t' /etc/passwd   grep '^r..t' /etc/passwd 

	*   	匹配前導符0次或多次		  grep 'ro*t' /etc/passwd

	.*		任意多個字元				grep 'r.*t' /etc/passwd

	[]		匹配指定範圍內的一個字元	grep '[rR]oot' /etc/passwd

	[ - ]	匹配指定範圍內的一個字元	grep'[a-z0-9]oot' /etc/passwd,如果要去大小寫a-z的話可以這麼寫[a-zA-Z]或者[a-Z]

	[ ^ ]	匹配不在指定組內的字元		grep '[^a-z0-9]oot' /etc/passwd 過濾不包含a-z0-9的oot的字元
	\		用來轉義元字元			   grep 'love\.' love.txt
	\<		詞首定位符				grep '\<root' /etc/passwd
    \>		詞尾定位符				grep 'root\>' /etc/passwd
    \(..\)	匹配稍後使用的字元的標籤只適用於替換,在bash不支援   %s /(\192.168.81.\)250/\1251/g
    x\{m\}	字元x重複出現m次			grep 'o\{5\}' /etc/passwd
    x\{m,\}	字元x重複出現m次以上		   grep 'o\{5,\}' /etc/passwd
    x\{m,n\}	字元x重複出現m到n次		grep 'o{2,5\}' /etc/passwd
	
	==================================幾個例子==================================
grep '\<root\>' /etc/passwd             //限制詞首和詞尾都是root的單詞
grep '^\<root\>' /etc/passwd            //僅是以root單詞開頭的行

%s/192.168.81.250/192.168.81.251/g              //正常情況在vim中要改一個字元
%s/\(192.168.81.\)250/\1251/g                   //利用正則\(..\)來改,這種情況在:如果要改的字元前一部分跟之前一樣,可以使用\(\)在括號中把相同的部分在括號中寫好,然後>在使用\1呼叫第一個括號中的內容,如果是定義了兩個括號就使用\2呼叫第二個括號中的內容
%s#\(192.168.81\).250#\1.251#g                  //這個原理和上調命令一致,#等同於/
%s#\(192.\)\(168.\)\(81.\)250#\1\2\3251#g               //多括號
%s/\(192\).\(168\).\(81\).250/\1.\2.\3.251/g
3,8 s/\(.*\)/#\1                        //3-8行在每行前面加一個#

egrep 'ro*' /etc/passwd //匹配o出現0或多次
egrep 'ro{2}' /etc/passwd       //匹配o出現2次
egrep 'ro{2,}' /etc/passwd      //匹配o出現2次以上
egrep 'ro{2,5}' /etc/passwd     //匹配o出現兩次到五次

grep 'ro*' /etc/passwd  //匹配o出現0或多次
grep 'ro\{2\}' /etc/passwd      //匹配o出現2次
grep 'ro\{2,\}' /etc/passwd     //匹配o出現2次以上
grep 'ro\{2,5\}' /etc/passwd    //匹配o出現兩次到五次   

2.2擴充套件正則表示式元字元

擴充套件元字元的意思和基礎的一致,就是省略了一些特殊符號用egrep來進行匹配

+		匹配一個或多個前導字元		[a-z]+ove
?		匹配0個或1個前導字元		  lo?ve
a|b		匹配a或b				love|hate
()		組字元					loveable|rs	love(able|rs)ov+ ov+(ov)+	組字元也就是匹配括號中的內容,ov+是v一個或多個,(ov)+是ov兩個字元一個或多個
    (..)(..)\1\2	標籤匹配字元		(love)able\1er和基礎元字元一樣
x{m}	字元x重複m次		o{5}
x{m,}	字元x重複至少m次	o{5,}
x{m,n}	字元x重複m到n次	o{5,10}
=========================例子========================
egrep 'ro+t' /etc/passwd        //o出現1次或多次
egrep 'ro?t' /etc/passwd        //o出現0次或1次
egrep 'root|jxl' /etc/passwd    //匹配root或者jxl的行
netstat -lnpt -an | egrep ':80|:22\>'   //匹配80或者22號埠
egrep 'ro(ot|or)' /etc/passwd           //組字元,匹配ot或者or
egrep 'r(o)+t' /etc/passwd              //組字元o出現多次

2.3.POSIX字元類

這種型別類似於系統的環境變數,由系統定義好的,我們來用就行

表示式					功能							例項

[:alnum:]			字母與數字字元					[[:alnum:]]+	//字母和數字出現多次

[:alpha:]			字母字元(包括大小寫字母)		[[:alpha:]]{4}		//字母字元出現四次

[:blank:]			空格與製表符					 [[:blank:]]*	//出現0次到多次

[:digit:]			數字字母					  [[:digit:]]?	//出現0次或1次

[:lower:]			小寫字母				      [[:lower:]]{5,}		//出現5次以上

[:upper:]			大寫字母				      [[:upper:]]+		//出現一次或多次

[:punct:]			標點符號				      [[:punct:]]

[:space:]			包括換行符,回車等在內的所有空白  [[:space:]]+

3.正則匹配例項:vim

/love/				//匹配love的行
/^love/			//以love開頭的行
/love$/			//以love結尾的行
/l.ve/				//l後面任意一個字元ove的行
/lo*ve/			//o可以出現0次到多次
/[Ll]ove/			//L或者l任意其中一個
/love[a-z]/		//love後面跟一個a-z字元的行
/love[^a-zA-Z0-9]			//除去a-zA-Z0-9的行


/.*/			//任意多個字元表示一行
/^$/			//空行,有一個回車
/^[A-Z]..$/			//以大寫A-Z開頭再跟後面有兩個字元的行
/^[A-Z][a-z]*3[0-5]/		//以大寫字母A-Z開頭在跟a-z出現0次或多次再跟3在跟一個0-5的數字
/[a-z]*\./			//a-z出現0次到多次後面在跟個點
/^ *[A-Z][a-z][a-z]$/	//以0個到多個空行開頭在跟一個包含A-Z的在跟一個包含在跟一個a-z的包含a-z結尾的行
/^[A-Za-z]*[^,][A_Za-z]*$/		//以A-Z或者a-z開頭0個到多個在跟一個非逗號在跟一個A-Z或a-z0到多個結尾的
/\<fourth\>			//匹配一個單詞
/\<f.*th/>			//匹配一個f開頭th結尾的單詞
\5{2}2{3}\./ 		//5出現2次,2出現3次在跟一個點


空行
/^$/		//空行
/^[ \t]*$/		//0到多個空格或tab鍵開頭或結尾的


註釋行
/^#/	//#開頭的行
/^[ \t]*#/		//以空格或tab鍵開頭的0到多個在跟一個#

:1,$/\([Oo]ccur\)ence/\1rence/		//全文搜尋O或者occurence的行找到後利用標籤\1呼叫第一個括號後面在跟上rence
:1,$/(square\)and\(fair\)/\2 and \1/		//就是將第二個標籤的內容與第一個標籤的內容換了個位置

  1. 0-9 ↩︎