shell之正則表示式
一 正則表示式
正則表示式:描述某些字串匹配規則的工具
使用原因:程式設計過程中不可避免的遇到處理某些文字情況,有時候要查詢符合某些比較複雜規則的字串。正則表示式以非常簡單的程式碼完成。
常見的支援正則表示式的UNIX工具:
grep命令族:用於匹配文字行
sed流編輯器:用於改變輸入流
awk:用於處理字串的語言
more或者less等:檔案檢視程式
ed,vi或者vim等:文字編輯器
實踐正則表示式:
#! /bin/bash
str=`catversion.txt|grep rev`
echo"$str"
(cat命令用來顯示文字內容,豎線是管道,表示將cat命苦的輸出結果作為後面的那個命令的輸入,
grep命令用來查詢文字,rev指要匹配的字串。上面執行結果表示version.txt檔案中的某一行含義rev這個字串,實際上,grep命令後面的引數可以換成任意的正則表示式)
1.1 正則表示式原理
正則表示式是對文字進行過濾的工具,之所以有過濾文字的功能,因為它定義了一系列的元字元,通過元字元配合其他字元來表達出一種規則。只有符合該規則的文字才能保留下來。
元字元:描述字元的字元。
元字元作用:對錶達式的內容,轉換以及各種操作資訊進行描述。
1.2 基本正則表示式
又稱標準正則表示式,僅支援最基本的元字符集。
基本正則表示式定義的元字元主要有:
1)行首定位符 “^”
用來匹配行首的字元。表示行首的字元是
^後面的那個字元。行首定位符位於所作用的字元之前
例如:
#列出/etc目錄中的以字母po開頭的檔名
str=`ls /etc |grep "^po"`
echo"$str"
(^po理解為第一個字元為p,緊跟著一個字母o的文字行。不要理解為字串po開頭的文字行。)
2)行尾定位符”$”
作用:定位文字行的末尾。
行尾定位符位於所作用的字元之後。
#列出/etc目錄中以conf結尾的檔名
str=`ls /etc |grep "conf$"`
echo"$str"
結果:anthy-conf
asound.conf
注意:
精確匹配一個文字行:^cat$ 完全匹配cat的文字行
^$:
匹配所有空行單獨的^和$沒有任何意義,因為任何一個文字行都有開頭和結尾。
3)單個字元匹配”.”
圓點.用來匹配任意單個字元。包括空格,但不包括換行符\n。當使用”.”後,意味著該位置一定有一個字元,無論他是什麼字元。
例:
#列出所有的包含字串“samba”的檔名,不管samba後面有沒有字元
str=`ls /etc |grep "samba"`
echo"$str"
echo"==============================="
#列出包含字串samba,且samba後面只是含義一個字元
str=`ls /etc |grep "samba."`
echo"$str"
結果:samba
samba4
======================
samba4
(可以連續使用..來匹配多個字元,如l..p,匹配含義字母l,然後是兩個任意字元,再接著是字母p的字串)
4) 限定符“*”
限定符本身不代表任何字元,用來指定其前面的一個字元必須重複出現多次才能滿足匹配。而星號表示匹配其前導字元的任意次數,包括0次
#篩選出以字元s開頭,緊跟著1個字元s,再接著任意個字元s的檔名
str=`ls /etc |grep "^sss*"`
echo"$str"
結果:ssh
ssl
sssd
5) 字符集匹配“[]”
只要某個字串在方括號所在的位置上出現了方括號中的任意一個字元,就滿足匹配規則。
對於連續的數字或字母,可使用連字元-來表示一個範圍。
如:[a-f]表示匹配a到f中的任意一個字母
[0-9]匹配任意單個數字
#篩選所有以字元r開頭,並且緊跟著1個字元c的文字行
str=`ls /etc |grep "^rc"`
echo "$str"
echo "=============================="
#篩選所有以字元r開頭,緊跟著1個字元為c,下面1個字元為單個數字的文字行
str=`ls /etc | grep "^rc[0-9]"`
echo "$str"
6)字符集不匹配“[^]”
1.3 擴充套件正則表示式
(egrep命令預設使用擴充套件正則表示式)
1 )限定符“+”
“+”限定前面的字元至少出現一次。
#篩選以字串“ss”開頭,後面至少緊跟著1個字元“s”的文字行
str=`ls /etc |egrep "^sss+"`
echo"$str"
結果:sssd
2)限定符“?”
限定前面的字元最多隻出現一次。
#篩選以字串“ss”開頭,後面跟著0或者1個s的文字行
str=`ls /etc |egrep "^sss?"`
echo"$str"
結果:ssh,ssl,sssd
3)豎線“|”和圓括號“()”
豎線|表示多個正則表示式之前或的關係
圓括號表示一組可選值得集合。
豎線和圓括號經常一起使用,表示一組可選值。
#篩選含有字串“ssh”、“ssl”或者以字串“yum”開頭的文字行
str=`ls /etc |egrep "(ssh|ssl|^yum)"`
echo"$str"
1.4 Perl正則表示式
1)數字匹配\d
2)非數字匹配\D
3)空白字元匹配\s
4)非空白字元匹配\S
1.5正則表示式應用
匹配單個字元
1 單個一般字元
英文字元,數字,空白字元以及標點符號
#搜尋demo2.txt含有字元“a”的文字行
str=`grep"a" demo2.txt`
echo"$str"
2 轉義後的元字元
要匹配元字元本身,需要在這些字元的前面加上\,關閉這些元字元的特殊意義,保留其字面意義。
反斜線也是一個元字元,如果要匹配,也要加\,即表示式“\\”表示匹配一個反斜線。
3 方括號表示式
當元字元位於方括號中時,除了連字元-或者^之外,其他元字元都會失去特殊意義。如:
[\.]表示的是反斜線\和圓點.這兩個字元。如果要匹配圓點,[.]就可以了。
匹配多個字元
1 將多個字元按照指定順序拼接起來
#搜尋字串“matter”
str=`grep"matter" demo3.txt`
echo"$str"
2 方括號或星號等配合
#匹配任意多個字元“o”
str=`grep"lo*king" demo3.txt`
echo"$str"
例子:篩選符合指定格式的電話號碼
#篩選符合格式的電話號碼
str=`egrep"800-[[:digit:]]{3}-[[:digit:]]{4}$" demo4.txt`
echo"$str"
1.6 正則表示式優先順序
\ 轉義符
[] 方括號表示式
() 分組
*,+?{m},{m,},{m,n} 限定符
普通字元從左到右順序
^,$ 定位符
| 或運算
(從高到低)
1.7 子表示式
由多個普通字元或者元字元組成的一個小的正則表示式。作為一個大的正則表示式的一部分使用,不能單獨使用。使用圓括號括起來。
例子:匹配IP地址
#匹配IP地址
str=`egrep"^([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}$" ip.txt`
echo"$str"
(子表示式表示匹配1-3個數字,然後是一個圓點。整個表示式描述的字串以3組重複的1-3個數字後跟一個圓點開頭,然後以1-3個數字結尾)
精確匹配IP地址:
#匹配正確IP地址
str=`egrep"^([0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"ip.txt`
echo"$str"
1.8 萬用字元
shell本身不支援正則表示式,使用正則表示式的是shell命令和工具。
shell使用了正則表示式中的某些元字元作為萬用字元,常用的有*,?,[],{},^等。但意義有所不同。
如:*表示匹配任意的字元,在非正則表示式中限制其前導字元的0次或多次重複。
例:
列出以ex開頭的當前目錄中所有的檔案:ls–l ex*
列出以字元d或e開頭的檔案:ls –l [de]*
1.9 grep命令
grep命令使用正則表示式來搜尋文字,並且把匹配的文字打印出來。
grep [options]pattern [file]
option表示選項,pattern表示匹配的模式。file表示一系列檔名。
常用選項:
-c 只打印匹配的文字行的函式,不顯示文字內容。
-i 匹配時忽略字母大小寫
-h 當搜尋多個檔案,不顯示匹配檔名字首。
-l 只列出含義匹配的文字行的檔案的檔名,不顯示其具體匹配的內容。
-n 列出所有匹配的文字行,並顯示行號
-s 不顯示關於不存在或無法讀取檔案的錯誤資訊
-v 只顯示不匹配的文字行。
-w 匹配整個單詞
-x 匹配整個文字行
-r 遞迴搜尋,不僅搜尋當前目錄,還有各級子目錄