正则表示法
时间:2006-01-24 来源:xwq_007
鳥哥的 Linux 私房菜
支持自由軟體,請愛用 firefox 瀏覽本網頁
本網頁主要以 firefox 配合解析度 1024x768 作為設計依據
http://linux.vbird.org/ is designed by VBird during 2001-2005. Aerosol Lab.
支持自由軟體,請愛用 firefox 瀏覽本網頁
正規表示法 Regular Expression, RE 切換解析度為 800x600 最近更新日期:2005/09/05
1. 前言: 2. 基礎正規表示法: 2.1 以 grep 擷取字串 2.2 重要特殊字元(characters) 3. 延伸正規表示法: 4. 格式化列印: printf 5. sed 工具簡介 6. awk 工具簡介 7. 文件資料比對與列印的相關功能 7.1 檔案比對: diff, cmp, patch 7.2 檔案列印準備: pr 8. 重點回顧 9. 參考資源 10.本章習題練習 前言 約略瞭解了 Linux 的基本指令 ( Shell ) 並且熟悉了 vi 之後,相信您對於敲擊鍵盤與指令比較不陌生了吧?? 接下來,底下要開始介紹一個很重要的觀念,那就是所謂的『正規表示法』囉! 什麼是正規表示法 任何一個有經驗的系統管理員,都會告訴您:『正規表示法真是挺重要的!』 為什麼很重要呢?因為日常生活就使用的到啊!舉個例子來說, 在您日常處理文書作業時,應該會常常使用到『搜尋/取代』等等的功能吧? 這些舉動要作的漂亮,就是正規表示法的工作了! 簡單的說,正規表示法就是處理字串的方法,他是以行為單位, 來進行字串的處理行為,他透過一些特殊符號的輔助,可以讓使用者輕易的達到 搜尋/取代 某特定字串的處理程序! 舉例來說,我要找到 VBird 或 Vbird 這個字樣,但是不要其他的字串,該如何辦理? 如果在沒有正規表示法的環境中(例如 MS word),您或許就得要使用忽略大小寫的辦法, 或者是分別以 VBird 及 Vbird 搜尋兩遍。但是,忽略大小寫可能會搜尋到 VBIRD/vbird/VbIrD 等等的不需要的字串,而造成使用者的困擾。 再舉個系統常見的例子好了,假設妳發現系統在開機的時候,老是會出現一個關於 mail 程式的錯誤, 而開機過程的相關程序都是在 /etc/rc.d/ 底下,也就是說,在該目錄底下的某個檔案內具有 mail 這個關鍵字,好了,此時,您怎麼找出來含有這個關鍵字的檔案??您當然可以一個檔案一個檔案的開啟, 然後去搜尋 mail 這個關鍵字,只是.....該目錄底下的檔案可能不止 100 個說~ 如果瞭解正規表示法的相關技巧,那麼只要一行指令就找出來啦! 『grep 'mail' /etc/rc.d/*』 那個 grep 就是支援正規表示法的工具程式之一!如何~很簡單吧! ^_^y 談到這裡就得要進一步說明了,正規表示法基本上是一種『表示法』, 只要工具程式支援這種表示法,那麼該工具程式就可以用來作為正規表示法的字串處理之用。 也就是說,例如 vi, grep, awk ,sed 等等工具,因為她們有支援正規表示法, 所以,這些工具就可以使用正規表示法的特殊字元來進行字串的處理。 正規表示法對於系統管理員的用途 那麼為何我需要學習正規表示法呢?對於一般使用者來說,由於使用到正規表示法的機會可能不怎麼多, 因此感受不到他的魅力,不過,對於身為系統管理員的您來說, 正規表示法則是一個『不可不學的好東西!』 怎麼說呢?由於系統如果在繁忙的情況之下,每天產生的訊息資訊會多到你無法想像的地步, 而我們也都知道,系統的『錯誤訊息登錄檔案』 的內容(這部份我們在第五篇會詳談)記載了系統產生的所有訊息,當然, 這包含你的系統是否被『入侵』的紀錄資料。 但是系統的資料量太大了,要身為系統管理員的你每天去看這麼多的訊息資料, 從千百行的資料裡面找出一行有問題的訊息,呵呵~光是用肉眼去看,想不瘋掉都很難! 這個時候,我們就可以透過『正規表示法』的功能,將這些登錄的資訊進行處理, 僅取出『有問題』的資訊來進行分析,哈哈!如此一來,你的系統管理工作將會 『快樂得不得了』啊!當然,正規表示法的優點還不止於此,等您有一定程度的瞭解之後,您會愛上他喔! 正規表示法的廣泛用途 正規表示法除了可以讓系統管理員管理主機更為便利之外,事實上, 由於正規表示法強大的字串處理能力,目前一堆軟體都支援正規表示法呢! 最常見的就是『郵件伺服器』啦! 如果您留意網際網路上的消息,那麼應該不能發現,目前造成網路大塞車的主因之一就是『垃圾/廣告信件』了, 而如果我們可以在主機端,就將這些問題郵件剔除的話,用戶端就會減少很多不必要的頻寬耗損了。 那麼如何剔除廣告信件呢?由於廣告信件幾乎都有一定的標題或者是內容,因此, 只要每次有來信時,都先將來信的標題與內容進行特殊字串的比對,發現有不良信件就予以剔除! 嘿!這個工作怎麼達到啊?就使用正規表示法啊!目前兩大郵件伺服器軟體 sendmail 與 postfix 以及支援郵件伺服器的相關分析套件,都支援正規表示法的比對功能! 當然還不止於此啦,很多的伺服器軟體、以及套件都支援正規表示法呢!當然, 雖然各家軟體都支援他,不過,這些『字串』的比對還是需要系統管理員來加入比對規則的, 所以啦!身為系統管理員的你,為了自身的工作以及用戶端的需求, 正規表示法實在是很需要也很值得學習的一項工具呢! 正規表示法與 Shell 在 Linux 當中的角色定位 說實在的,我們在學數學的時候,一個很重要、但是粉難的東西是一定要『背』的, 那就是九九乘法表,背成功了之後,未來在數學應用的路途上,真是一帆風順啊! 這個九九乘法表我們在小學的時候幾乎背了一整年才背下來,並不是這麼好背的呢! 但他卻是基礎當中的基礎!您現在一定受惠相當的多呢 ^_^! 而我們談到的這個正規表示法,與前一章的 BASH shell 就有點像是數學的九九乘法表一樣,是 Linux 基礎當中的基礎,雖然也是最難的部分, 不過,如果學成了之後,一定是『大大的有幫助』的!這就好像是金庸小說裡面的學武難關, 任督二脈,打通任督二脈之後,武功立刻成倍成長!所以啦, 不論是對於系統的認識與系統的管理部分,他都有很棒的輔助啊!請好好的學習這個基礎吧! ^_^ 延伸的正規表示法 正規表示法除了簡單的一組字串處理之外,還可以作群組的字串處理, 例如進行搜尋 VBird 或 netman 或 lman 的搜尋,注意,是『或(or)』而不是『和(and)』的處理, 此時就需要延伸正規表示法的幫助啦!藉由特殊的 ( 與 | 等字元的協助, 就能夠達到這樣的目的!好啦!清清腦門,咱們用功去囉!
既然正規表示法是處理字串的一個標準表示方式,他需要支援的工具程式來輔助, 所以,我們這裡就先介紹一個最簡單的字串擷取功能的工具程式,那就是 grep 囉! 在介紹完 grep 的基本功能之後,就進入正規表示法的特殊字符的處理能力了。 以 grep 擷取字串 既然要使用 grep 當然就得要先瞭解一下 grep 的語法囉~
而 grep 除了可以進行檔案的資料搜尋之外,也常常被應用在 input/output 的資料處理當中,例如常見的 管線命令 ( pipe ) 就可以常常見到他的蹤影! 以上面表格中的例子來看,我們可以發現前兩個例子是查尋檔案的內容,有沒有加上 -v 所顯示出來的結果是『相反的!』,而第三個例子則是以 pipe 的功能進行資料的處理的喔! 好了,我們就開始以 grep 來進行正規表示法的簡易說明吧!我們先以底下這個檔案來作為範例:
經過了上面的幾個簡單的範例,我們可以將基礎的正規表示法特殊字符彙整如下:
請特別留意的是,『正規表示法的特殊字元』 與一般在指令列輸入指令的『萬用字元』並不相同, 例如,在萬用字元當中,* 代表的是 0 ~ 無限多個字元的意思,但是在正規表示法當中, * 則是重複 0 到多個的前一個 RE 字符的意思~使用的意義並不相同,不要搞混了! (鳥哥我一開始摸正規表示法時就很容易搞混!因為這裡是新手最容易搞錯的地方,特別小心啊!) 舉例來說,不支援正規表示法的 ls 這個工具中,若我們使用 『ls -l * 』 代表的是任意檔名的檔案,而 『ls -l a* 』代表的是以 a 為開頭的任何檔名的檔案, 但在正規表示法中,我們要找到含有以 a 為開頭的檔案,則必須要這樣:(需搭配支援正規表示法的工具)
延伸正規表示法 事實上,一般讀者只要瞭解基礎型的正規表示法大概就已經相當足夠了,不過,某些時刻, 為了要簡化整個指令操作,瞭解一下使用範圍更廣的延伸型正規表示法的表示式,會更方便呢! 舉個簡單的例子好了,在上節的例題三的最後一個例子中,我們要去除空白行與行首為 # 的行列, 使用的是
這裡必須要特別強調, grep 支援的是基礎型的正規表示法,而 egrep 支援延伸正規表示法。 事實上, egrep 是 grep -E 的命令別名,為了方便使用,我們還是以 egrep 來跟 grep 區分吧! 熟悉了正規表示法之後,到這個延伸型的正規表示法,您應該也會想到, 不就是多幾個重要的特殊符號嗎? ^_^y 是的~所以,我們就直接來說明一下,延伸型正規表示法有哪幾個特殊符號?
以上這些就是延伸型的正規表示法的特殊字元。另外,要特別強調的是,那個 ! 在正規表示法當中並不是特殊字元, 所以,如果您想要查出來檔案中含有 ! 與 > 的字行時,可以這樣:
在很多時候,我們可能需要將輸出的資料給他格式化輸出的~ 舉例來說,考試卷分數的輸出,姓名與科目及分數之間,總是可以稍微作個比較漂亮的版面配置吧? 例如我想要輸出底下的樣式:
在瞭解了一些正規表示法的基礎應用之後,再來呢?呵呵~兩個東西可以玩一玩的,那就是 sed 跟 awk 了! 這兩個傢伙可是相當的有用的啊!舉例來說,鳥哥寫的 logfile.sh 分析登錄檔的小程式, 絕大部分分析關鍵字的取用、統計等等,就是用這兩個寶貝蛋來幫我完成的! 那麼你說,要不要玩一玩啊?! ^_^ 我們先來談一談 sed 好了,基本上, sed 可以分析 Standard Input (STDIN) 的資料, 然後將資料經過處理後,再將他輸出到 standrad out (STDOUT) 的一個工具。 至於處理呢?可以進行取代、刪除、新增、擷取特定行等等的功能呢!很不錯吧~ 我們先來瞭解一下 sed 的用法,再來聊他的用途好了!
awk 工具簡介 相較於 sed 常常作用於一整個行的處理, awk 則比較傾向於一行當中分成數個『欄位』來處理。 因此,awk 相當的適合處理小型的數據資料處理呢!awk 通常運作的模式是這樣的:
另外,由上面這個例子您也會知道,在每一行的每個欄位都是有變數名稱的,那就是 $1, $2... 等變數名稱,以上面的例子來說, dmtsai 是 $1 ,因為他是第一欄嘛!至於 192.168.1.12 是第三欄, 所以他就是 $3 啦!後面以此類推~呵呵!還有個變數喔!那就是 $0 ,$0 代表『一整列資料』的意思~ 以上面的例子來說,第一行的 $0 代表的就是『dmtsai pts/0.... 』那一行啊! 由此可知,剛剛上面四行當中,整個 awk 的處理流程是:
我們繼續以上面例子來做說明,如果我想要列出每一行的帳號,並且列出目前處理的行數, 並且說明,該行有多少欄位,則可以這樣 (注意, awk 後續的所有動作以 ' 括住, 所以,內容如果想要以 print 列印時,記得,非變數的文字部分,包含上一小節 printf 提到的格式中,都需要使用雙引號來定義出來喔!)
awk 的邏輯運算字元 既然有需要用到 "條件" 的類別,自然就需要一些邏輯運算囉~例如底下這些:
值得注意的是那個 == 的符號,因為在『邏輯運算』上面, 就是所謂的大於、小於、等於等等的判斷式上面,我們習慣上是以 == 來表示,而如果是直接給予一個值,例如變數設定時,就直接使用 = 而已。 好了,我們實際來運用一下邏輯判斷吧!舉例來說,在 /etc/passwd 當中是以冒號 ":" 來作為欄位的分隔,那假設我要查閱,第三欄小於 10 以下的數據,並且僅列出帳號與第三欄, 那麼可以這樣做:
除此之外, awk 還可以幫我們進行迴圈計算喔!真是相當的好用! 不過,那屬於比較進階的單獨課程了,我們這裡就不再多加介紹。如果您有興趣的話, 可以到中研院的網站查詢喔:http://phi.sinica.edu.tw/aspac/reports/94/94011/,鳥哥這裡也有一份 pdf 檔的備份: http://linux.vbird.org/linux_basic/0330regularex/awk.pdf。 您可以自行參閱一下該文章的內容,裡頭可以好好的查閱一下關於陣列與迴圈方面的介紹, 我認為該文章寫的很棒喔!該介紹的都介紹了!很好~我喜歡~ ^_^ 文件資料比對與列印的相關功能 正規表示法是相當有用的工具,當然,那個 sed 還有 awk 也是很棒的工具程式, 不過,除此之外,我們其實還有很多可以使用的工作來處理文件資料喔! 舉例來說,假如我有兩個檔案,一個檔案是原始檔,一個則是經過一些時間累積處理後的檔案, 我想要知道這兩個檔案之間的差別,該如何運用正規表示法?呼呼~可能要透過所謂的迴圈來一行一行比對檢查呢~ 但是,我們可以透過 Linux 提供的 diff 及 cmp 指令來進行比對即可喔!很棒的啊! 檔案比對 什麼時候會用到檔案的比對啊?通常是『同一個套裝軟體的不同版本之間,比較設定檔與原始檔的差異』, 所以囉,很多時候所謂的檔案比對,通常是用在 ASCII 純文字檔的比對上的! 那麼比對檔案的指令有哪些?最常見的就是 diff 囉!
如果您曾經使用過一些圖形介面的文書處理軟體的話,那麼很容易發現, 當我們在列印的時候,可以同時選擇與設定每一頁列印時的標頭吧! 也可以設定頁碼呢!那麼,如果我是在 Linux 底下列印純文字檔呢 可不可以具有標題啊?可不可以加入頁碼啊?呵呵!當然可以啊! 使用 pr 就能夠達到這個功能了。不過, pr 的參數實在太多了, 我也說不完,一般來說,我都僅使用最簡單的方式來處理而已。 舉例來說,如果想要列印 /etc/man.config 呢?
( 要看答案請將滑鼠移動到『答:』底下的空白處,按下左鍵圈選空白處即可察看 )
2003/02/10:重新編排與加入 FAQ ; 2005/01/28:重新彙整基礎正規表示法的內容!重點在 regular_express.txt 的處理與練習上! 2005/03/30:修訂了 grep -n 'goo*g' regular_express.txt 這一段 2005/05/23:修訂了 grep -n '^[a-z]' regular_express.txt 所要擷取的是小寫,之前寫成大寫,錯了! 2005/08/22:加入了 awk, sed 等工具的介紹,還有 diff 與 cmp 等指令的說明! 2005/09/05:加入 printf 內,關於 \xNN 的說明! 2002/06/28 以來統計人數 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
本網頁主要以 firefox 配合解析度 1024x768 作為設計依據
http://linux.vbird.org/ is designed by VBird during 2001-2005. Aerosol Lab.
相关阅读 更多 +
排行榜 更多 +