linux的命令列可以勝任所有的工作,這和ms的產品有著很大的區別,到現在為止仍然有很多的愛好者對敲鍵盤樂此不疲,而在繁重的管理工作和鍵盤工作中,Regex對於簡化工作起到了很大的作用。 Perl regular expressions man page.http://www.perldoc.com/perl5.8.0/pod/perlre.html
一、Regex簡介 事實上,Regex不僅適用於linux,多種程式設計語言中也可以使用到它,因為它實際上是人們對於某種規律的表達方式。 如果要把他的所有應用都講上的話那這篇文章會變的太長以至於無法閱讀,我只介紹他在linux下和幾種最重要的命令的搭配使用。 基本的元字元集: ^行首 $行尾 *匹配星號前的字元一次或多次 []匹配[]內的字元,可以是一個字元也可以是字元列 \用來屏蔽一個元字元的特殊含義,可以使其失去原有的意義。 pattern\{n\}用來匹配前面pattern出現的次數。n為次數。 而其中使用最多的是行首和行尾,無論在任何地方都可能會用到它們,比如vi,你輸入$,就可以跳到行尾,在bbs上,你也可以輸入$,直接跳到這個版的最後的一篇文章。 後面所說的將是他們的和具體命令結合的例子。 二、grep 和Regex grep是個非常常用的工具,linux其實和internet一樣,都是一個充滿了大量資訊、資料的東西,如何有效過濾自己不用的資訊、擷取有用的資訊反映了一個人水平的高低,當我還是linux新手的時候還不懂得用grep呢。 一個最簡單的應用例子就是如何查看一個目錄裡只查看檔案夾了,ls並沒有提供這樣的參數給你,而是需要你用grep(或後面提到的awk)來實現這樣的功能。我們知道一個檔案夾的屬性為dxxx,所以我們可以用ls -l |grep ^d,即列印匹配行首第一個字母為d的項目,這樣就把所有的檔案夾列印出來而忽略其他非檔案夾的檔案了,舉一反三,我們可以用來匹配所有的許可權,比如我想找到所有許可權為rwx------的檔案,這樣我們就可以輸入ls -l|grep ^.rwx,其中.號為匹配任意一個字元。再看下面的例子,想找許可權為----rw----的檔案,可以使用ls -l|grep ^....rw....,怎麼樣,這樣簡單多了吧,我們還可以尋找所有以*號結尾的檔案(在某些linux上用它來代表可執行檔)即ls |grep \*$,要注意的是必須加\以屏蔽*號的原來的特殊意義,而$號是加在行尾的。 可以用^符號來再非Regex的意思(即否定)如前面我說了要看檔案夾,那麼如果我想看不是檔案夾的檔案怎麼辦 : ls -l|grep ^[^d],這樣的意思就是說查看所有行首不為d字母的項,當然也可以用grep 的-v選項實現同樣功能。不過今天重點是說Regex,所以就不講參數了。 我還可以尋找多個檔案,如有一個目錄裡面有我需要的內容,我只知道他在某個.doc檔案裡頭,我可以用grep "運算式" *.doc,而這個運算式就需要你去想了,有www.2cto.com多種方法可以指定模糊的運算式,如k...D,代表以小寫字母k開頭,中間三個是任一字元而以大寫字母D結尾的字串,而k*D,則表達以k開頭中間可以是任意長度任一字元的而以D結尾的字串,還可以用[]指定範圍,如[12345]day,指的是以1到6中任意一個字元開頭後面是day的字串,像3day就匹配這個運算式而13day就不匹配。[Ss]可以指定以大寫S或者小寫s的字元,而像結合pattern\{n\}還可以用更奇妙的用法,我就不多說了。 三、awk和Regex awk對於從大的資料檔案中抽取指定的資料包十分有用,比如你可以用他來管理passwd檔案,或者是記錄檔(相當巨大的檔案,而用了awk就會變的很輕鬆了),通常awk都是和grep結合來用的,又grep抽出行,再有awk抽出行中指定的列,不過就算單獨用awk也一樣好用。請看看這樣的例子 awk -F: '{if($6 ~ /bash/) print $0}' /etc/passwd 這是個相當複雜的例子,我舉這個例子的目的只是為了說明結合命令文法和Regex可以實現相當強的過濾作用,這個命令的作用是從passwd檔案中的第六列中www.2cto.com抽取所有含有bash的項目然後在列印這些項目的第一項即他們的使用者名稱。我假設passwd為這樣的內容 root:*:*:*:*:*:/bin/bash user:*:*:*:*:*:/bin/bash xie:*:*:*:*:*:/bin/csh ftp:*:*:*:*:*:/bin/zsh 那麼輸出就應該為 root user 我們逐個來分析,首先 -F:指定:為分隔字元,因為預設的分隔字元是空格,然後我們用一個假設語句,因為假設語句和後面的print組合成一個動作,所以必須用花括弧括起來,意思是如果(if)第六列($6)匹配(~)字串bash,那麼列印(print)第零列($0)。其中/bash/指的是匹配bash,//只是起括起來的作用,並不參與判斷。 awk有自己的Regex和條件操作符,他比一般的Regex要多出兩個元字元,就是+和?,+使用匹配一個或多個字元。匹配模式出現頻率,例如使用/XY?Z/匹配XYZ,或YZ。條件操作符有 =大於等於 ~匹配Regex !~不匹配Regex 結合以上運算式,還可以作出更多的動作,如 ls -l|awk 'BEGIN {print "Name\t SIZE"} {if /^[^d]/} {print $9 "\t" $5} {tot+=5} END {print "total KB:"tot}' 可以用此運算式來列印檔案名幾其長度,然後輸出所有檔案加起來的大小。 他相當與於我前面所說的先找出不是檔案夾的檔案,然後列印他們的大小和長度,把這些大小值放入變數tot中,放一次加一次(+=),最後列印tot,就可以把所有檔案的大小求出來了。 邏輯符號 && AND,必須同時為真 ! 非,求逆 awk '{if ($3=="root" && $5="/root") print $0}' /etc/passwd 當組和個人目錄都為root的時候列印使用者的名字。 嘿嘿,事實上awk還有算術操作符呢,我為了偷懶就不寫了,不過上面已經有例子了(用了+=),就留給大家慢慢研究吧。 四、VI和Regex 文書編輯更加用用到Regex了,比如說在編輯狀態下輸入^,可以跳到行中第一個非Null 字元,輸入$,可以跳到本行行尾(在行號表示的時候,$代表最後一行)。輸入/可以搜尋字串,同樣可以使用Regex匹配,如/^str,則匹配行首的str,輸入/str$,則匹配行尾的str。其他的和Regex方法一樣。 五、總結 linux還有更複雜的sed也會用到Regex,事實上大部分和資訊過濾有關的都離不開他,不過小子才疏學淺,實在是寫不了了,僅以此文拋磚引玉,不過各位大俠可千萬別因為我這篇文章寫的差而全把磚頭往我招呼啊…… 還有一點是給初學者的:記得多用|管道和檔案操作符啊,0代表標準輸入、1代表標準輸出、2代表錯誤輸出,其他還有3-9你是可以任意使用的,如可以先把某檔案指到操作符4,再把4指向0,那麼就可以作為程式的輸入了。
作者 神父不怕鬼吹燈