bashshell中的正則表達式
俗話說,工欲善其事,必先利其器。由于很多Linux的文本處理工具普遍使用到了正則表達式,因此,不理解正則表達式就無法愉快的從事Linux日常系統管理。那什么是正則表達式呢?
正則表達式(RegularExpression)主要由普通字符和元字符組成。例如:鍵盤上的英文字母和數字都屬于普通字符,普通字符可以以正常人類思維去理解,a就是英文的小寫字母a,Shell沒有任何隱藏含義。而^,*,#,這些比較詭異的元字符,Shell賦予了它們超越自身的意義。你可能認為*只是一個乘法符號,但實際上卻表示了重復前面的字符0次或多次的隱藏含義。
實際上,正則表達式在數據流處理的過程中完成的是數據過濾,也就是將滿足正則表達式定義的數據留下來,將不滿足正則表達式的數據拒絕掉。下面我們來看一看正則表達式能留住哪些元字符
正則表達式:
* 匹配任意個字符,0個或多個
. 匹配任意單個字符
.* 匹配任意字符
^ 匹配行首
$ 匹配行尾
[] 匹配字符集合
\<\> 精確匹配單詞符號
\{n\} 匹配之前的字符n次
\{n,\} 至少匹配之前的字符n次
\{n,m\} 至少匹配之前的字符n次,至多m次
除了上述的正則表達式外,Linux工具中的awk,grep,perl等工具還支持擴展的正則表達式
擴展正則表達式
? 匹配一個或0個在其之前的普通字符
+ 至少匹配一個在其之前的普通字符,相當于\{1,\}
() 匹配一個字符集合
| 表示或,用來匹配一組可選字符串
POSIX字符類
[:upper:] 表示所有大寫字母
[:lower:] 表示所有小寫字母
[:alnum:] 表示所有大小寫字母和數字
[:space:] 表示空白字符
[:alpha:] 表示所有大小寫字母
[:digit:] 表示所有數字
[:cntrl:] 表示Ctrl鍵
好了,了解了這么多元字符,可以大展身手了,用到正則表達式莫過于grep,egrep,fgrep三兄弟了
grep 基本的文本查找工具,支持正則表達式
egrep 拓展grep命令,支持基本和擴展正則表達式
fgrep 快速grep命令,不支持任何正則表達式,只是按照字符的原意進行匹配
其實egrep和fgrep分別可以使用grep -E或者grep -F命令替代
grep [OPTIONS] PATTERN [FILE…]
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE…]
OPTIONS:
-v 反向選取
-o 僅顯示匹配到的字符串,而非行
-b 用于配合-o,可顯示匹配到字符的偏移值
-i 忽略字符大小寫
-E 支持拓展正則表達式
-F 忽略所有正則表達式
-A # 顯示匹配行的后#行(#為整數)
-B # 顯示匹配行的前#行
-C # 顯示匹配行的前后各#行
PATTERN 匹配模式(當然就是由正則表達式和元字符組成啦)
FILE 查找的文件(可以由多個文件組成)
grep同時匹配的文件可以有多個,但匹配模式只能有一個
例如:當前目錄有如下文件
輸入grep root passwd?和grep root bin passwd?的對比結果
想必細心地你也發現了FILE一項也可以使用正則表達式
例1:如果我想查找/proc/partitions中關于設備sda的相關信息,那么你可能要用到精確匹配
grep '\<sda\>' /proc/partitions
8 0 20971520 sda
這樣就不會匹配到sda設備下的其他分區
例2:在/etc/profile文件下有許多空白開頭的行,可以使用精確匹配來獲取它們
grep "^[[:space:]]\{1,\}" /etc/profile
例3:如何匹配電子郵件地址?
標準的電子郵箱地址一般為 email@mail.com
grep "[[:alnum:]]\{1,\}@[[:alnum:]]\{1,\}\.[[:alpha:]]\{2,4\}"
[[:alnum:]]\{1,\}表示在@出現之前,[]內的字符組合至少出現一次或多次,而后的[[:alnum:]]\{1,\}也是如此,\.將元字符轉義成普通字符,而[[:alpha:]]\{2,4\}表示字母長度應該最少出現2次,最多出現4次
例4:想要匹配ifconfig命令中的IP地址可以使用以下方式
ifconfig | grep '[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}'
當然這種方式也會匹配不合法的IP地址,那如果我們想匹配C類地址怎么辦呢?(192.0.0.0-223.255.255.254)
ifconfig | egrep -o '\<(19[2-9]|2[0-1][0-9]|22[0-3])\>.\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>.\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>.\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\>'
原創文章,作者:賣糖術士,如若轉載,請注明出處:http://www.www58058.com/4377