Linux命令中正則表達式的運用

linux的命令行可以勝任所有的工作,這和ms的產品有着很大的區別,到現在爲止仍然有很多的愛好者對敲鍵盤樂此不疲,而在繁重的管理工作和鍵盤工作中,正則表達式對於簡化工作起到了很大的作用。

Perl regular expressions man page.
http://www.perldoc.com/perl5.8.0/pod/perlre.html

一、正則表達式簡介
事實上,正則表達式不僅適用於linux,多種編程語言中也可以使用到它,因爲它實際上是人們對於某種規律的表達方式。
如果要把他的所有應用都講上的話那這篇文章會變的太長以至於無法閱讀,我只介紹他在linux下和幾種最重要的命令的搭配使用。
基本的元字符集:
^行首
$行尾
*匹配星號前的字符一次或多次
[]匹配[]內的字符,可以是一個字符也可以是字符列
/用來屏蔽一個元字符的特殊含義,可以使其失去原有的意義。
pattern/{n/}用來匹配前面pattern出現的次數。n爲次數。

而其中使用最多的是行首和行尾,無論在任何地方都可能會用到它們,比如vi,你輸入$,就可以跳到行尾,在bbs上,你也可以輸入$,直接跳到這個版的最後的一篇文章。
後面所說的將是他們的和具體命令結合的例子。

二、grep 和正則表達式
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 /*$,要注意的是必須加/以屏蔽*號的原來的特殊意義,而$號是加在行尾的。

可以用^符號來再非正則表達式的意思(即否定)如前面我說了要看文件夾,那麼如果我想看不是文件夾的文件怎麼辦 : ls -l|grep ^[^d],這樣的意思就是說查看所有行首不爲d字母的項,當然也可以用grep 的-v選項實現同樣功能。不過今天重點是說正則表達式,所以就不講參數了。

我還可以查找多個文件,如有一個目錄裏面有我需要的內容,我只知道他在某個.doc文件裏頭,我可以用grep "表達式" *.doc,而這個表達式就需要你去想了,有多種方法可以指定模糊的表達式,如k...D,代表以小寫字母k開頭,中間三個是任意字符而以大寫字母D結尾的字符串,而k*D,則表達以k開頭中間可以是任意長度任意字符的而以D結尾的字符串,還可以用[]指定範圍,如[12345]day,指的是以1到6中任意一個字符開頭後面是day的字符串,像3day就匹配這個表達式而13day就不匹配。[Ss]可以指定以大寫S或者小寫s的字符,而像結合pattern/{n/}還可以用更奇妙的用法,我就不多說了。


三、awk和正則表達式
awk對於從大的數據文件中抽取指定的數據包十分有用,比如你可以用他來管理passwd文件,或者是日誌文件(相當巨大的文件,而用了awk就會變的很輕鬆了),通常awk都是和grep結合來用的,又grep抽出行,再有awk抽出行中指定的列,不過就算單獨用awk也一樣好用。請看看這樣的例子
awk -F: '{if($6 ~ /bash/) print $0}' /etc/passwd
這是個相當複雜的例子,我舉這個例子的目的只是爲了說明結合命令語法和正則表達式可以實現相當強的過濾作用,這個命令的作用是從passwd文件中的第六列中抽取所有含有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有自己的正則表達式和條件操作符,他比一般的正則表達式要多出兩個元字符,就是+和?,+使用匹配一個或多個字符。?匹配模式出現頻率,例如使用/XY?Z/匹配XYZ,或YZ。條件操作符有
<小於
<=小於等於
==等於(這個和C語言是一樣的)
!=不等於
>=大於等於
~匹配正則表達式
!~不匹配正則表達式

結合以上表達式,還可以作出更多的動作,如
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和正則表達式
文書編輯更加用用到正則表達式了,比如說在編輯狀態下輸入^,可以跳到行中第一個非空字符,輸入$,可以跳到本行行尾(在行號表示的時候,$代表最後一行)。輸入/可以搜索字符串,同樣可以使用正則表達式匹配,如/^str,則匹配行首的str,輸入/str$,則匹配行尾的str。其他的和正則表達式方法一樣。

 

五、總結
linux還有更復雜的sed也會用到正則表達式,事實上大部分和信息過濾有關的都離不開他,不過小子才疏學淺,實在是寫不了了,僅以此文拋磚引玉,不過各位大俠可千萬別因爲我這篇文章寫的差而全把磚頭往我招呼啊……
還有一點是給初學者的:記得多用|管道和文件操作符啊,0代表標準輸入、1代表標準輸出、2代表錯誤輸出,其他還有3-9你是可以任意使用的,如可以先把某文件指到操作符4,再把4指向0,那麼就可以作爲程序的輸入了。

http://blog.chinaunix.net/u/31547/showart_350800.html

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章