Posted on 2009-11-29 11:44
Gavin.lee 閱讀(606)
評論(0) 編輯 收藏 所屬分類:
Linux command
grep 指令
grep -- print lines matching a pattern (將符合樣式的該行列出)
◎語法: grep [options] PATTERN [FILE...]
grep (globalsearch regular expression(RE) and print out theline,全面搜索正則表達式并把行打印出來)是一種強大的文本搜索工具,它能使用正則表達式搜索文本,并把匹配的行打印出來。Unix的grep家族包括grep、 egrep和fgrep。egrep和fgrep的命令只跟grep有很小不同。egrep是grep的擴展,支持更多的re元字符,fgrep就是 fixed grep或fastgrep,它們把所有的字母都看作單詞,也就是說,正則表達式中的元字符表示回其自身的字面意義,不再特殊。linux使用GNU版本的grep。它功能更強,可以通過-G、-E、-F命令行選項來使用egrep和fgrep的功能。
grep的工作方式是這樣的,它在一個或多個文件中搜索字符串模板。如果模板包括空格,則必須被引用,模板后的所有字符串被看作文件名。搜索的結果被送到屏幕,不影響原文件內容。
grep可用于shell腳本,因為grep通過返回一個狀態值來說明搜索的狀態,如果模板搜索成功,則返回0,如果搜索不成功,則返回1,如果搜索的文件不存在,則返回2。我們利用這些返回值就可進行一些自動化的文本處理工作。
2. grep正則表達式元字符集(基本集)
^
錨定行的開始 如:'^grep'匹配所有以grep開頭的行。
$
錨定行的結束 如:'grep$'匹配所有以grep結尾的行。
匹配一個非換行符的字符 如:'gr.p'匹配gr后接一個任意字符,然后是p。
*
匹配零個或多個先前字符 如:'*grep'匹配所有一個或多個空格后緊跟grep的行。 .*一起用代表任意字符。
[]
匹配一個指定范圍內的字符,如'[Gg]rep'匹配Grep和grep。
[^]
匹配一個不在指定范圍內的字符,如:'[^A-FH-Z]rep'匹配不包含A-R和T-Z的一個字母開頭,緊跟rep的行。
(..)
標記匹配字符,如'(love)',love被標記為1。
<
錨定單詞的開始,如:'\>
錨定單詞的結束,如'grep>'匹配包含以grep結尾的單詞的行。
x{m}
重復字符x,m次,如:'0{5}'匹配包含5個o的行。
x{m,}
重復字符x,至少m次,如:'o{5,}'匹配至少有5個o的行。
x{m,n}
重復字符x,至少m次,不多于n次,如:'o{5,10}'匹配5--10個o的行。
w
匹配文字和數字字符,也就是[A-Za-z0-9],如:'Gw*p'匹配以G后跟零個或多個文字或數字字符,然后是p。
W
w的反置形式,匹配一個或多個非單詞字符,如點號句號等。
b
單詞鎖定符,如: 'bgrepb'只匹配grep。
3. 用于egrep和 grep -E的元字符擴展集
+
匹配一個或多個先前的字符。如:'[a-z]+able',匹配一個或多個小寫字母后跟able的串,如loveable,enable,disable等。
?
匹配零個或多個先前的字符。如:'gr?p'匹配gr后跟一個或沒有字符,然后是p的行。
a|b|c
匹配a或b或c。如:grep|sed匹配grep或sed
()
分組符號,如:love(able|rs)ov+匹配loveable或lovers,匹配一個或多個ov。
x{m},x{m,},x{m,n}
作用同x{m},x{m,},x{m,n}
4. POSIX字符類
為了在不同國家的字符編碼中保持一至,POSIX(The Portable Operating SystemInterface)增加了特殊的字符類,如[:alnum:]是A-Za-z0-9的另一個寫法。要把它們放到[]號內才能成為正則表達式,如[A-Za-z0-9]或[[: alnum:]]。在linux下的grep除fgrep外,都支持POSIX的字符類。
[:alnum:]
文字數字字符
[:alpha:]
文字字符
[:digit:]
數字字符
[:graph:]
非空字符(非空格、控制字符)
[:lower:]
小寫字符
[:cntrl:]
控制字符
[:print:]
非空字符(包括空格)
[:punct:]
標點符號
[:space:]
所有空白字符(新行,空格,制表符)
[:upper:]
大寫字符
[:xdigit:]
十六進制數字(0-9,a-f,A-F)
5. Grep命令選項
-?
同時顯示匹配行上下的?行,如:grep -2 pattern filename同時顯示匹配行的上下2行。
-b,--byte-offset
打印匹配行前面打印該行所在的塊號碼。
-c,--count
只打印匹配的行數,不顯示匹配的內容。
-f File,--file=File
從文件中提取模板。空文件中包含0個模板,所以什么都不匹配。
-h,--no-filename
當搜索多個文件時,不顯示匹配文件名前綴。
-i,--ignore-case
忽略大小寫差別。
-q,--quiet
取消顯示,只返回退出狀態。0則表示找到了匹配的行。
-l,--files-with-matches
打印匹配模板的文件清單。
-L,--files-without-match
打印不匹配模板的文件清單。
-n,--line-number
在匹配的行前面打印行號。
-s,--silent
不顯示關于不存在或者無法讀取文件的錯誤信息。
-v,--revert-match
反檢索,只顯示不匹配的行。
-w,--word-regexp
如果被<和>引用,就把表達式做為一個單詞搜索。
-V,--version
顯示軟件版本信息。
6. 實例
要用好grep這個工具,其實就是要寫好正則表達式,所以這里不對grep的所有功能進行實例講解,只列幾個例子,講解一個正則表達式的寫法。
$ ls -l | grep '^a'
通過管道過濾ls -l輸出的內容,只顯示以a開頭的行。
$ grep 'test' d*
顯示所有以d開頭的文件中包含test的行。
$ grep 'test' aa bb cc
顯示在aa,bb,cc文件中匹配test的行。
$ grep '[a-z]{5}' aa
顯示所有包含每個字符串至少有5個連續小寫字符的字符串的行。
$ grep 'w(es)t.*1' aa
如果west被匹配,則es就被存儲到內存中,并標記為1,然后搜索任意個字符(.*),這些字符后面緊跟著另外一個es(1),找到就顯示該行。如果用egrep或grep -E,就不用""號進行轉義,直接寫成'w(es)t.*1'就可以了。
默認情況下,‘grep’只搜索當前目錄。如果此目錄下有許多子目錄,‘grep’會以如下形式列出:
grep: sound: Is a directory
這可能會使‘grep’的輸出難于閱讀。這里有兩種解決的辦法:
明確要求搜索子目錄:grep -r
或忽略子目錄:grep -d skip
當然,如果預料到有許多輸出,您可以通過 管道 將其轉到‘less’上閱讀:
$ grep magic /usr/src/linux/Documentation/* | less
這樣,您就可以更方便地閱讀。
有一點要注意,您必需提供一個文件過濾方式(搜索全部文件的話用 *)。如果您忘了,‘grep’會一直等著,直到該程序被中斷。如果您遇到了這樣的情況,按 <CTRL c> ,然后再試。
配合管道(|)進行搜索:
grep -C number pattern files :匹配的上下文分別顯示[number]行,
grep pattern1 | pattern2 files :顯示匹配 pattern1 或 pattern2 的行,
grep pattern1 files | grep pattern2 :顯示既匹配 pattern1 又匹配 pattern2 的行。
用于搜索的特殊符號:
\< 和 \> 分別標注單詞的開始與結尾。
例如:
grep man * 會匹配 ‘Batman’、‘manic’、‘man’等,
grep '\<man' * 匹配‘manic’和‘man’,但不是‘Batman’,
grep '\<man\>' 只匹配‘man’,而不是‘Batman’或‘manic’等其他的字符串。
'^':指匹配的字符串在行首,
'$':指匹配的字符串在行尾,
===========================================================================================
如果您不習慣命令行參數,可以試試圖形界面的‘grep’,如 reXgrep 。這個軟件提供 AND、OR、NOT 等語法,還有漂亮的按鈕 :-) 。如果您只是需要更清楚的輸出,不妨試試 fungrep
egrep
egrep代表expression或extended grep,適情況而定。egrep接受所有的正則表達式,egrep的一個顯著特性是可以以一個文件作為保存的字符串,然后將之傳給egrep作為參數,為此使用- f開關。
===========================================================================================
grep命令是linux下的行過濾工具,其參數繁多
◎參數
1. -A NUM,--after-context=NUM
除了列出符合行之外,并且列出后NUM行。
ex: $ grep -A 1 panda file
(從file中搜尋有panda樣式的行,并顯示該行的后1行)
2. -a或--text
grep原本是搜尋文字文件,若拿二進制的檔案作為搜尋的目標,
則會顯示如下的訊息: Binary file 二進制文件名 matches 然后結束。
若加上-a參數則可將二進制檔案視為文本文件搜尋,
相當于--binary-files=text這個參數。
ex: (從二進制檔案mv中去搜尋panda樣式)
(錯誤!!!)
$ grep panda mv
Binary file mv matches
(這表示此檔案有match之處,詳見--binary-files=TYPE )
$
(正確!!!)
$ grep -a panda mv
3. -B NUM,--before-context=NUM
與 -A NUM 相對,但這此參數是顯示除符合行之外
并顯示在它之前的NUM行。
ex: (從file中搜尋有panda樣式的行,并顯示該行的前1行)
$ grep -B 1 panda file
4. -C [NUM], -NUM, --context[=NUM]
列出符合行之外并列出上下各NUM行,默認值是2。
ex: (列出file中除包含panda樣式的行外并列出其上下2行)
(若要改變默認值,直接改變NUM即可)
$ grep -C[NUM] panda file
5. -b, --byte-offset
列出樣式之前的內文總共有多少byte ..
ex: $ grep -b panda file
顯示結果類似于:
0:panda
66:pandahuang
123:panda03
6. --binary-files=TYPE
此參數TYPE預設為binary(二進制),若以普通方式搜尋,只有2種結果:
1.若有符合的地方:顯示Binary file 二進制文件名 matches
2.若沒有符合的地方:什么都沒有顯示。
若TYPE為without-match,遇到此參數,
grep會認為此二進制檔案沒有包含任何搜尋樣式,與-I 參數相同。
若TPYE為text, grep會將此二進制文件視為text檔案,與-a 參數相同。
Warning: --binary-files=text 若輸出為終端機,可能會產生一些不必要的輸出。
7. -c, --count
不顯示符合樣式行,只顯示符合的總行數。
若再加上-v,--invert-match,參數顯示不符合的總行數。
8. -d ACTION, --directories=ACTION
若輸入的檔案是一個資料夾,使用ACTION去處理這個資料夾。
預設ACTION是read(讀取),也就是說此資料夾會被視為一般的檔案;
若ACTION是skip(略過),資料夾會被grep略過:
若ACTION是recurse(遞歸),grep會去讀取資料夾下所有的檔案,
此相當于-r 參數。
9. -E, --extended-regexp
采用規則表示式去解釋樣式。
10. -e PATTERN, --regexp=PATTERN
把樣式做為一個partern,通常用在避免partern用-開始。
11. -f FILE, --file=FILE
事先將要搜尋的樣式寫入到一個檔案,一行一個樣式。
然后采用檔案搜尋。
空的檔案表示沒有要搜尋的樣式,因此也就不會有任何符合。
ex: (newfile為搜尋樣式文件)
$grep -f newfile file
12. -G, --basic-regexp
將樣式視為基本的規則表示式解釋。(此為預設)
13. -H, --with-filename
在每個符合樣式行前加上符合的文件名稱,若有路徑會顯示路徑。
ex: (在file與testfile中搜尋panda樣式)
$grep -H panda file ./testfile
file:panda
./testfile:panda
$
14. -h, --no-filename
與-H參數相類似,但在輸出時不顯示路徑。
15. --help
產生簡短的help訊息。
16. -I
grep會強制認為此二進制檔案沒有包含任何搜尋樣式,
與--binary-files=without-match參數相同。
ex: $ grep -I panda mv
17. -i, --ignore-case
忽略大小寫,包含要搜尋的樣式及被搜尋的檔案。
ex: $ grep -i panda mv
18. -L, --files-without-match
不顯示平常一般的輸出結果,反而顯示出沒有符合的文件名稱。
19. -l, --files-with-matches
不顯示平常一般的輸出結果,只顯示符合的文件名稱。
20. --mmap
如果可能,使用mmap系統呼叫去讀取輸入,而不是預設的read系統呼叫。
在某些狀況,--mmap 能產生較好的效能。 然而,--mmap
如果運作中檔案縮短,或I/O 錯誤發生時,
可能造成未定義的行為(包含core dump),。
21. -n, --line-number
在顯示行前,標上行號。
ex: $ grep -n panda file
顯示結果相似于下:
行號:符合行的內容
22. -q, --quiet, --silent
不顯示任何的一般輸出。請參閱-s或--no-messages
23. -r, --recursive
遞歸地,讀取每個資料夾下的所有檔案,此相當于 -d recsuse 參數。
24. -s, --no-messages
不顯示關于不存在或無法讀取的錯誤訊息。
小注: 不像GNU grep,傳統的grep不符合POSIX.2協議,
因為缺乏-q參數,且他的-s 參數表現像GNU grep的 -q 參數。
Shell Script傾向將傳統的grep移植,避開-q及-s參數,
且將輸出限制到/dev/null。
POSIX: 定義UNIX及UNIX-like系統需要提供的功能。
25. -V, --version
顯示出grep的版本號到標準錯誤。
當您在回報有關grep的bugs時,grep版本號是必須要包含在內的。
26. -v, --invert-match
顯示除搜尋樣式行之外的全部。
27. -w, --word-regexp
將搜尋樣式視為一個字去搜尋,完全符合該"字"的行才會被列出。
28. -x, --line-regexp
將搜尋樣式視為一行去搜尋,完全符合該"行"的行才會被列出。