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命令中輸入字符串參數時,最好將其用雙引號括起來。
在調用模式匹配時,應使用單引號。
開始討論之前,先生成一個文件,插入一段文本,并在每列后加入< Ta b >鍵,g r e p命令示例中絕大多數將以此為例,其命名為d
a t a . . f。生成一個文件,d a t a . f的記錄結構如下:
第1列:城市位置編號。
第2列:月份。
第3列:存儲代碼及出庫年份。
第4列:產品代號。
第5列:產品統一標價。
第6列:標識號。
第7列:合格數量。
文件內容如下:
- $ 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”
2、 行匹配
1)顯示包含“4 8”字符串的文本:
2)輸出匹配行的總數
g r e p返回數字4,表示:包含字符串“4 8”的有4行。
3)行數
顯示滿足匹配模式的所有行行數:
行數在輸出第一列,后跟包含4 8的每一匹配行。
4)顯示非匹配行
顯示所有不包含4 8的各行
5)精確匹配
可能大家已注意到,在上一例中,抽取字符串“ 4 8”,返回結果包含諸如4 8 4和4 8 3等包含“4
8”的其他字符串,實際上應精確抽取只包含4 8的各行。
使用g r e p抽取精確匹配的一種更有效方式是在抽取字符串后加\ >。假定現在精確抽取4 8,方法如下:
另一種方法我試過,好像不行:
注意在每個匹配模式中抽取字符串后有一個< 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,既有大寫也有小寫,要取得此字符串大小寫不敏感查詢,方法如下:
grep和正則表達式
使用正則表達式使模式匹配加入一些規則,因此可以在抽取信息中加入更多選擇。使用正則表達式時最好用單引號括起來,這樣可以防止g r e
p中使用的專有模式與一些s h e l l命令的特殊方式相混淆。
1、模式范圍
抽取代碼為4 8 4和4 8 3的城市位置,可以使用[ ]來指定字符串范圍。
- $ 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,可以在方括號中使用^記號。
- $ grep "^[^48]" data.f
- 219 dec 2CC1999 CAD 23.00 PLV2C 68
- 216 sept 3ZL1998 USP 86.00 KVM9E 234
如果是字符串48
- $ grep -v "^[^48]"
data.f
3、設置大小寫
使用- i開關可以屏蔽月份S e p t的大小寫敏感
- [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的所有信息。
- [sam@chenwy sam]$ grep
'[sS]ept' data.f
如果要抽取包含S e p t的所有月份,不管其大小寫,并且此行包含字符串483,可以使用管道命令,即符號“|”左邊命令的輸出作為“
|”右邊命令的輸入。舉例如下:
- [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個字符:
- [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結尾:
- [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。
- [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之間,使用下列模式即可實現。
- [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
這里返回很多信息,有想要的,也有不想要的。參照模式,返回結果是正確的,因此這里
- [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至少重復出現兩次的所有行,方法如下:
- [sam@chenwy sam]$ grep
'4\{2,\}' data.f
- 483 may 5PA1998 USP 37.00 KVM9D 644
上述語法指明數字4至少重復出現兩次,注意有無邊
界字符的區別。
同樣,抽取記錄使之包含數字9 9 9(三個9),方法如下:
- [sam@chenwy sam]$ grep
'9\{3,\}' data.f
- 219 dec 2CC1999 CAD 23.00 PLV2C 68
如果要查詢重復出現次數一定的所有行,語法如下,數字9重復出現兩次或三次:
- [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結尾:
- [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,方法如下:
- [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參數顯示總行數:
- [sam@chenwy sam]$ grep
-c '^$' myfile
使用- n參數顯示實際在哪一行:
- [sam@chenwy sam]$ grep
-c '^$' myfile
10、匹配特殊字符
查詢有特殊含義的字符,諸如$ . ' " * [] ^ | \ + ? ,必須在特定字符前加\。假設要查詢包含“.”的所有行,腳本如下:
- [sam@chenwy sam]$ grep
'\.' myfile
或者是一個雙引號:
- [sam@chenwy sam]$ grep
'\"' myfile
以同樣的方式,如要查詢文件名c o n f t r o l l . c o n f(這是一個配置文件),腳本如下:
- [sam@chenwy sam]$ grep
'conftroll\.conf' myfile
11、查詢格式化文件名
使用正則表達式可匹配任意文件名。系統中對文本文件有其標準的命名格式。一般最多六個小寫字符,后跟句點,接著是兩個大寫字符。
- [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次,后跟句點。
- [0-9]\{3\}\.[0-9]\{3\}\.'
shell基礎八:文本過濾工具(grep)
1、類名
g r e p允許使用國際字符模式匹配或匹配模式的類名形式。
類名及其等價的正則表達式類等價的正則表達式類等價的正則表達式
[ [ : 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開頭,后跟至少兩個大寫字母:
- $grep
'5[[:upper:]][[:upper]]' data.f
取以P或D結尾的所有產品代碼:
- grep
'[[:upper:]][[:upper:]][P,D]' data.f
2、使用通配符*的匹配模式
- $cat testfile
- looks
- likes
- looker
- long
試試如下:
如在行尾查詢某一單詞,試如下模式:
這將在所有文件中查詢行尾包含單詞ng的所有行。
3、系統grep
文件passwd
- [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字符串
如果誤輸入以下腳本:
- [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開關,可屏蔽錯誤信息。
返回命令提示符,而沒有文件不存在的錯誤提示。
- [root@Linux_chenwy sam]#
grep -s "sam" /etc/password
如果g r e p命令不支持- s開關,可替代使用以下命令:
- [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命令的查詢結果,可將命令輸出重定向到一個文件。
- [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),方法如下:
- [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命令使用管道輸入。
- [root@Linux_chenwy sam]#
STR="Mary Joe Peter Pauline"
- [root@Linux_chenwy sam]# echo $STR | grep "Mary"
- Mary Joe Peter Pauline
匹配成功實現。
- [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接受所有的正則表達式, 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:
- [root@Linux_chenwy sam]#
vi grepstrings
- [root@Linux_chenwy sam]# cat grepstrings
- 484
- 47
- [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,可以使用(|)符號,意即“|”符號兩邊之一或全部。
- [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。
- $who |egrep
(louise|matty|pauline)
還可以使用^符號排除字符串。如果要查看系統上的用戶,但不包括m a t t y和p a u l i n e,方法如下:
- $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可容易地實現。
- $egrep '(shutdown
|reboot) (s)?' *
from:
http://bbs.chinaunix.net/thread-446683-1-1.html
posted on 2010-06-01 09:48
chatler 閱讀(439)
評論(0) 編輯 收藏 引用 所屬分類:
Shell