Linux Shell指令碼之正則表示式
阿新 • • 發佈:2022-05-10
正則表示式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/ //就是將第二個標籤的內容與第一個標籤的內容換了個位置
0-9 ↩︎