shell基礎八:文本過濾工具(grep)

來源:互聯網
上載者:User
From:http://bbs.chinaunix.net/viewthread.php?tid=446683

QUOTE: 原帖由 "網中人" 發表:
比方以 grep 來說, 在 Linux 上你可找到 grep, egrep, fgrep 這幾個程式, 其差異大致如下:

* grep:
傳統的 grep 程式, 在沒有參數的情況下, 只輸出符合 RE 字串之句子. 常見參數如下:
-v: 逆反模示, 只輸出"不含" RE 字串之句子.
-r: 遞迴模式, 可同時處理所有層級子目錄裡的檔案.
-q: 靜默模式, 不輸出任何結果(stderr 除外. 常用以擷取 return value, 符合為 true, 否則為 false .)
-i: 忽略大小寫.
-w: 整詞比對, 類似 /<word/> .
-n: 同時輸出行號.
-c: 只輸出符合比對的行數.
-l: 只輸出符合比對的檔案名稱.
-o: 只輸出符合 RE 的字串. (gnu 新版專屬, 不見得所有版本都支援.)
-E: 切換為 egrep .

* egrep:
為 grep 的擴充版本, 改良了許多傳統 grep 不能或不便的操作. 比方說:
- grep 之下不支援 ? 與 + 這兩種 modifier, 但 egrep 則可.
- grep 不支援 a|b 或 (abc|xyz) 這類"或一"比對, 但 egrep 則可.
- grep 在處理 {n,m} 時, 需用 /{ 與 /} 處理, 但 egrep 則不需.
諸如此類的... 我個人會建議能用 egrep 就不用 grep 啦... ^_^

* fgrep:
不作 RE 處理, 運算式僅作一般字串處理, 所有 meta 均失去功能.

g r e p一般格式為:

[Copy to clipboard] [ - ]

CODE:

grep [選項]基本Regex[檔案]
這裡基本Regex可為字串。

單引號雙引號
在g r e p命令中輸入字串參數時,最好將其用雙引號括起來。

在調用模式比對時,應使用單引號。

例如:“m y s t r i n g”。這樣做有兩個原因,一是以防被誤解為s h e l l命令,二是可以用來尋找多個單片語成的字串。
在調用變數時,也應該使用雙引號,諸如: g r e p“$ M Y VA R”檔案名稱,如果不這樣,將沒有返回結果。

常用的g r e p選項有:

QUOTE:-c 只輸出匹配行的計數。
-i 不區分大小寫(只適用於單字元)。
-h 查詢多檔案時不顯示檔案名稱。
-l 查詢多檔案時只輸出包含匹配字元的檔案名稱。
-n 顯示匹配行及行號。
-s 不顯示不存在或無匹配文本的錯誤資訊。
-v 顯示不包含匹配文本的所有行。

開始討論之前,先產生一個檔案,插入一段文本,並在每列後加入< Ta b >鍵,g r e p命令樣本中絕大多數將以此為例,其命名為d a t a . . f。產生一個檔案,d a t a . f的記錄結構如下:

QUOTE:第1列:城市位置編號。
第2列:月份。
第3列:儲存代碼及出庫年份。
第4列:產品代號。
第5列:產品統一標價。
第6列:標識號。
第7列:合格數量。

檔案內容如下:

[Copy to clipboard] [ - ]

CODE:

$ cat data.f
48      Dec     3BC1977 LPSX    68.00   LVX2A   138
483     Sept    5AP1996 USP     65.00   LVX2C   189
47      Oct     3ZL1998 LPSX    43.00   KVM9D   512
219     dec     2CC1999 CAD     23.00   PLV2C   68
484     nov     7PL1996 CAD     49.00   PLV2C   234
483     may     5PA1998 USP     37.00   KVM9D   644
216     sept    3ZL1998 USP     86.00   KVM9E   234


1、查詢多個檔案
在所有檔案中查詢單詞“ sort it”

[Copy to clipboard] [ - ]

CODE:

$ grep "sort it" *

2、 行匹配
1)顯示包含“4 8”字串的文本:

[Copy to clipboard] [ - ]

CODE:

$ grep  "48"data.f

2)輸出匹配行的總數

[Copy to clipboard] [ - ]

CODE:

$ grep -c "48"data.f
4

g r e p返回數字4,表示:包含字串“4 8”的有4行。

3)行數
顯示滿足匹配模式的所有行行數:

[Copy to clipboard] [ - ]

CODE:

$ grep -n "48"data.f

行數在輸出第一列,後跟包含4 8的每一匹配行。

4)顯示非匹配行
顯示所有不包含4 8的各行

[Copy to clipboard] [ - ]

CODE:

$ grep -v "48"data.f

5)精確匹配
可能大家已注意到,在上一例中,抽取字串“ 4 8”,返回結果包含諸如4 8 4和4 8 3等包含“4 8”的其他字串,實際上應精確抽取只包含4 8的各行。
使用g r e p抽取精確匹配的一種更有效方式是在抽取字串後加/ >。假定現在精確抽取4 8,方法如下:

[Copy to clipboard] [ - ]

CODE:

$grep "48/>" data.f

QUOTE:另一種方法我試過,好像不行:
注意在每個匹配模式中抽取字串後有一個< Ta b >鍵,所以應操作如下:
< Ta b >表示點擊t a b鍵。
$grep "48<tab>" data.f

6)大小寫敏感
預設情況下, g r e p是大小寫敏感的,如要查詢大小寫不敏感字串,必須使用- i開關。在d a t a . f檔案中有月份字元S e p t,既有大寫也有小寫,要取得此字串大小寫不敏感查詢,方法如下:

[Copy to clipboard] [ - ]

CODE:

$grep -i "48" data.f

grep和Regex

使用Regex使模式比對加入一些規則,因此可以在抽取資訊中加入更多選擇。使用Regex時最好用單引號括起來,這樣可以防止g r e p中使用的專有模式與一些s h e l l命令的特殊方式相混淆。
                                                                              
1、模式範圍
抽取代碼為4 8 4和4 8 3的城市位置,可以使用[ ]來指定字串範圍。

[Copy to clipboard] [ - ]

CODE:

$ grep "48[34]" data.f
483     Sept    5AP1996 USP     65.00   LVX2C   189
484     nov     7PL1996 CAD     49.00   PLV2C   234
483     may     5PA1998 USP     37.00   KVM9D   644

2、不匹配行首
使行首不是4或8,可以在方括弧中使用^記號。

[Copy to clipboard] [ - ]

CODE:

$ grep "^[^48]" data.f
219     dec     2CC1999 CAD     23.00   PLV2C   68
216     sept    3ZL1998 USP     86.00   KVM9E   234

如果是字串48

[Copy to clipboard] [ - ]

CODE:

$ grep -v "^[^48]" data.f

3、設定大小寫
使用- i開關可以屏蔽月份S e p t的大小寫敏感

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep -i "sept" data.f
483     Sept    5AP1996 USP     65.00   LVX2C   189
216     sept    3ZL1998 USP     86.00   KVM9E   234

也可以用另一種方式[ ]模式抽取各行包含S e p t和s e p t的所有資訊。

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep '[sS]ept' data.f

如果要抽取包含S e p t的所有月份,不管其大小寫,並且此行包含字串483,可以使用管道命令,即符號“|”左邊命令的輸出作為“ |”右邊命令的輸入。舉例如下:

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep '[sS]ept' data.f | grep 48
483     Sept    5AP1996 USP     65.00   LVX2C   189

不必將檔案名稱放在第二個g r e p命令中,因為其輸入資訊來自於第一個g r e p命令的輸出
                                                                              
4、匹配任一字元
如果抽取以K開頭,以D結尾的所有代碼,可使用下述方法,因為已知代碼長度為5個字元:

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep 'K...D' data.f
47      Oct     3ZL1998 LPSX    43.00   KVM9D   512
483     may     5PA1998 USP     37.00   KVM9D   644

將上述代碼做輕微改變,頭兩個是大寫字母,中間兩個任意,並以C結尾:

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep '[A-Z]..C' data.f
483     Sept    5AP1996 USP     65.00   LVX2C   189
219     dec     2CC1999 CAD     23.00   PLV2C   68
484     nov     7PL1996 CAD     49.00   PLV2C   234

5、日期查詢
一個常用的查詢模式是日期查詢。先查詢所有以5開始以1 9 9 6或1 9 9 8結尾的所有記錄。使用模式5 . . 1 9 9 [ 6 , 8 ]。這意味著第一個字元為5,後跟兩個點,接著是1 9 9,剩餘兩個數字是6或8。

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep '5..199[6,8]' data.f
483     Sept    5AP1996 USP     65.00   LVX2C   189
483     may     5PA1998 USP     37.00   KVM9D   644

6、範圍組合
必須學會使用[ ]抽取資訊。假定要取得城市代碼,第一個字元為0-9,第二個字元在0到5之間,第三個字元在0到6之間,使用下列模式即可實現。

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep '[0-9][0-5[0-6]' data.f
48      Dec     3BC1977 LPSX    68.00   LVX2A   138
483     Sept    5AP1996 USP     65.00   LVX2C   189
47      Oct     3ZL1998 LPSX    43.00   KVM9D   512
219     dec     2CC1999 CAD     23.00   PLV2C   68
484     nov     7PL1996 CAD     49.00   PLV2C   234
483     may     5PA1998 USP     37.00   KVM9D   644
216     sept    3ZL1998 USP     86.00   KVM9E   234

這裡返回很多資訊,有想要的,也有不想要的。參照模式,返回結果是正確的,因此這裡

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep '^[0-9][0-5][0-6]' data.f
219     dec     2CC1999 CAD     23.00   PLV2C   68
216     sept    3ZL1998 USP     86.00   KVM9E   234

這樣可以返回一個預期的正確結果。
                                                                       以下要注意有無邊界字元的區別       
7、模式出現機率
抽取包含數字4至少重複出現兩次的所有行,方法如下:

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep '4/{2,/}' data.f
483     may     5PA1998 USP     37.00   KVM9D   644

上述文法指明數字4至少重複出現兩次,注意有無邊界字元的區別。                                                                              
同樣,抽取記錄使之包含數字9 9 9(三個9),方法如下:

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep '9/{3,/}' data.f
219     dec     2CC1999 CAD     23.00   PLV2C   68

如果要查詢重複出現次數一定的所有行,文法如下,數字9重複出現兩次或三次:

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep '9/{3/}' data.f
219     dec     2CC1999 CAD     23.00   PLV2C   68
[sam@chenwy sam]$ grep '9/{2/}' data.f
483     Sept    5AP1996 USP     65.00   LVX2C   189
47      Oct     3ZL1998 LPSX    43.00   KVM9D   512
219     dec     2CC1999 CAD     23.00   PLV2C   68
484     nov     7PL1996 CAD     49.00   PLV2C   234

有時要查詢重複出現次數在一定範圍內,比如數字或字母重複出現2到6次,下例匹配數字8重複出現2到6次,並以3結尾:

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ cat myfile
83
888883
8884
88883
[sam@chenwy sam]$ grep '8/{2,6/}3' myfile
888883
88883

8、使用grep匹配“與”或者“或”模式
g r e p命令加- E參數,這一擴充允許使用擴充模式比對。例如,要抽取城市代碼為2 1 9或2 1 6,方法如下:

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep -E '219|216' data.f
219     dec     2CC1999 CAD     23.00   PLV2C   68
216     sept    3ZL1998 USP     86.00   KVM9E   234

9、空行
結合使用^和$可查詢空行。使用- c參數顯示總行數:

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep -c '^$' myfile

使用- n參數顯示實際在哪一行:

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep -c '^$' myfile

10、匹配特殊字元
查詢有特殊含義的字元,諸如$ . ' " * [] ^ | / + ? ,必須在特定字元前加/。假設要查詢包含“.”的所有行,指令碼如下:

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep '/.' myfile

或者是一個雙引號:

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep '/"' myfile

以同樣的方式,如要查詢檔案名稱c o n f t r o l l . c o n f(這是一個設定檔),指令碼如下:

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep 'conftroll/.conf' myfile

11、查詢格式檔案名
使用Regex可匹配任意檔案名稱。系統中對文字檔有其標準的命名格式。一般最多六個小寫字元,後跟句點,接著是兩個大寫字元。

[Copy to clipboard] [ - ]

CODE:

[sam@chenwy sam]$ grep '^[a-z]/{1,6/}/.[A-Z]/{1,2/}' filename

這個寫法我不知道有沒有錯 :oops:  :oops:  :oops:
                                                                              
12 查詢IP地址
要查看n n n . n n n網路地址,如果忘了第二部分中的其餘部分,只知有兩個句點,例如n n n . n n . .。要抽取其中所有nnn.nnn IP地址,使用[ 0 - 9 ] / { 3 / } / . [ 0 - 0 / { 3 / } /。含義是任一數字出現3次,後跟句點,接著是任一數字出現3次,後跟句點。

[Copy to clipboard] [ - ]

CODE:

[0-9]/{3/}/.[0-9]/{3/}/.'

上面還有一點錯,改天更正



1、類名

g r e p允許使用國際字元模式比對或匹配模式的類名形式。
類名及其等價的Regex類等價的Regex類等價的Regex

QUOTE:[ [ : u p p e r : ] ] [ A - Z ] [ [ : a l n u m : ] ] [ 0 - 9 a - zA-Z]
[ [ : l o w e r : ] ] [ a - z ] [ [ : s p a c e : ] ] 空格或t a b鍵
[ [ : d i g i t : ] ] [ 0 - 9 ] [ [ : a l p h a : ] ] [ a - z A - Z ]

例一:取以5開頭,後跟至少兩個大寫字母:

[Copy to clipboard] [ - ]

CODE:

$grep '5[[:upper:]][[:upper:]]' data.f

取以P或D結尾的所有產品代碼:

[Copy to clipboard] [ - ]

CODE:

grep '[[:upper:]][[:upper:]][P,D]' data.f

2、使用萬用字元*的匹配模式

[Copy to clipboard] [ - ]

CODE:

$cat testfile
looks
likes
looker
long

試試如下:

[Copy to clipboard] [ - ]

CODE:

grep "l.*s" testfile

如在行尾查詢某一單詞,試如下模式:

[Copy to clipboard] [ - ]

CODE:

grep "ng$" testfile

這將在所有檔案中查詢行尾包含單詞ng的所有行。

3、系統grep

檔案passwd

[Copy to clipboard] [ - ]

CODE:

[root@Linux_chenwy sam]# grep "sam" /etc/passwd
sam:x:506:4::/usr/sam:/bin/bash

上述指令碼查詢/ e t c / p a s s w d檔案是否包含sam字串

如果誤輸入以下指令碼:

[Copy to clipboard] [ - ]

CODE:

[root@Linux_chenwy sam]# grep "sam" /etc/password
grep: /etc/password: 沒有那個檔案或目錄

將返回g r e p命令錯誤碼'No such file or directory'。
上述結果表明輸入檔案名稱不存在,使用g r e p命令- s開關,可屏蔽錯誤資訊。
返回命令提示字元,而沒有檔案不存在的錯誤提示。

[Copy to clipboard] [ - ]

CODE:

[root@Linux_chenwy sam]# grep -s "sam" /etc/password

如果g r e p命令不支援- s開關,可替代使用以下命令:

[Copy to clipboard] [ - ]

CODE:

[root@Linux_chenwy sam]# grep "sam" /tec/password >/dev/null 2>&1

指令碼含義是匹配命令輸出或錯誤( 2 > $ 1),並將結果輸出到系統池。大多數系統管理員稱/ d e v / n u l l為位元池,沒關係,可以將之看成一個無底洞,有進沒有出,永遠也不會填滿。

上述兩個例子並不算好,因為這裡的目的只想知道查詢是否成功。

如要儲存g r e p命令的查詢結果,可將命令輸出重新導向到一個檔案。

[Copy to clipboard] [ - ]

CODE:

[root@Linux_chenwy sam]# grep "sam" /etc/passwd >/usr/sam/passwd.out
[root@Linux_chenwy sam]# cat /usr/sam/passwd.out
sam:x:506:4::/usr/sam:/bin/bash

指令碼將輸出重新導向到目錄/ t m p下檔案p a s s w d . o u t中。

使用ps命令
使用帶有ps x命令的g r e p可查詢系統上啟動並執行進程。ps x命令意為顯示系統上啟動並執行所有進程列表。要查看D N S伺服器是否正在運行(通常稱為n a m e d),方法如下:

[Copy to clipboard] [ - ]

CODE:

[root@Linux_chenwy sam]# ps ax|grep "named"
2897 pts/1    S      0:00 grep named

輸 出也應包含此g r e p命令,因為g r e p命令建立了相應進程, ps x將找到它。在g r e p命令中使用- v選項可丟棄p s命令中的g r e p進程。如果ps x不適用於使用者系統,替代使用ps -ef。這裡,由於我沒有DNS服務,因而只有grep進程。

對一個字串使用grep
g r e p不只應用於檔案,也可應用於字串。為此使用e c h o字串命令,然後對g r e p命令使用管道輸入。

[Copy to clipboard] [ - ]

CODE:

[root@Linux_chenwy sam]# STR="Mary Joe Peter Pauline"
[root@Linux_chenwy sam]# echo $STR | grep "Mary"
Mary Joe Peter Pauline

匹配成功實現。

[Copy to clipboard] [ - ]

CODE:

[root@Linux_chenwy sam]# echo $STR | grep "Simon"

因為沒有匹配字串,所以沒有輸出結果。

4、egrep
e g r e p代表e x p r e s s i o n或extended grep,適情況而定。e g r e p接受所有的Regex, e g r e p的一個顯著特性是可以以一個檔案作為儲存的字串,然後將之傳給e g r e p作為參數,為此使用- f開關。如果建立一個名為g r e p s t r i n g s的檔案,並輸入4 8 4和4 7:

[Copy to clipboard] [ - ]

CODE:

[root@Linux_chenwy sam]# vi grepstrings
[root@Linux_chenwy sam]# cat grepstrings
484
47

[Copy to clipboard] [ - ]

CODE:

[root@Linux_chenwy sam]# egrep -f grepstrings data.f
47      Oct     3ZL1998 LPSX    43.00   KVM9D   512
484     nov     7PL1996 CAD     49.00   PLV2C   234

上述指令碼匹配d a t a . f中包含4 8 4或4 7的所有記錄。當匹配大量模式時, - f開關很有用,而在一個命令列中敲入這些模式顯然極為繁瑣。

如果要查詢儲存代碼3 2 L或2 C C,可以使用(|)符號,意即“|”符號兩邊之一或全部。

[Copy to clipboard] [ - ]

CODE:

[root@Linux_chenwy sam]# egrep '(3ZL|2CC)' data.f
47      Oct     3ZL1998 LPSX    43.00   KVM9D   512
219     dec     2CC1999 CAD     23.00   PLV2C   68
216     sept    3ZL1998 USP     86.00   KVM9E   234

可以使用任意多豎線符“ |”,例如要查看在系統中是否有帳號l o u i s e、m a t t y或pauline ,使用w h o命令並管道輸出至e g r e p。

[Copy to clipboard] [ - ]

CODE:

$who |egrep (louise|matty|pauline)

還可以使用^符號排除字串。如果要查看系統上的使用者,但不包括m a t t y和p a u l i n e,方法如下:

[Copy to clipboard] [ - ]

CODE:

$who |egrep -v '^(matty|pauline)'

如果要查詢一個檔案清單,包括s h u t d o w n、s h u t d o w n s、r e b o o t和r e b o o t s,使用e g r e p可容易地實現。

[Copy to clipboard] [ - ]

CODE:

$egrep '(shutdown |reboot) (s)?' *

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.