如何使用Unix/Linux grep命令 ——磨刀不誤砍柴工系列
Garygaowork#gmail.com
grep在一個或多個檔案中尋找與模式字串(pattern)匹配的行,並將搜尋的結果列印出來,不會修改原檔案內容。
使用grep 命令的文法為:
$grep [option(s)] pattern
其中option為grep命令的選項,pattern為要匹配的簡單字串或攜帶特殊字元的模式字串,file為檔案清單,可有多個檔案。
Part 1 grep中經常用到的選項(option)
-i 忽略pattern中的大小寫
$grep -i hAL /etc/passwd
-w 搜尋整個詞彙
忽略大小寫並搜尋整個詞彙"samba"
$grep -iw "samba" /tec/samba/smb.conf # This is the main Samba configuration file. You should read the # here. Samba has a huge number of configurable options (perhaps too # For a step to step guide on installing, configuring and using samba, # read the Samba-HOWTO-Collection. This may be obtained from:
-r 遞迴地指定檔案所在目錄中的所有子目錄中的檔案
-v 尋找與pattern不匹配的行
定義輸出方式:
-o 僅列印出匹配的一段,而非整行
-n 列印出匹配行的行號
-l 僅列印出匹配行所在的檔案
-c 列印出每個檔案中匹配行的總數
-A num 顯示匹配行之後的num行
-B num 顯示匹配行之前的num行
-C num 相當於 -A num 與 -B num 的組合
--color=auto 將pattern在匹配行中高亮輸出
注意:
(1).選項區分大小寫
(2).多個選項可以一起使用,例如:
$grep -iwr
(3).grep可用於shell指令碼,因為grep通過返回一個狀態值來說明搜尋的狀態,如果模板搜尋成功,則返回0,如果搜尋不成功,則返回1,如果搜尋的檔案不存在,則返回2。我們利用這些傳回值就可進行一些自動化的文本處理工作。
Part 2 在grep中使用Regex
1.基本的匹配模式
儘管直接使用最簡單直接的pattern字串可以完成一些重要任務,但是grep命令的真正威力在於它可以使用Regex來完成複雜的模式字串的匹配。grep命令中使用的是“基本的Regex”,如果想使用更進階的Regex規則,需要指定選項 -E ,相當於egrep命令。
以下字元或字串在Regex的規則中具有特殊意義,如,*,+,[,],^,$,\,{,}
它們的多種組合展示了基本的Regex的匹配模式:
(1)'.'匹配任意單一字元
(2) X* 與包含連續0個或多個字元X的行匹配
(3) X\+ 與包含連續1個或多個字元X的行匹配
(4) [a-z] 與包含a-z的其中一個字元的行匹配
(5) [^a-z] 與不包含a-z的其中一個字元的行匹配
(6) [0-9] 與包含0-9的其中一個字元的行匹配
(7) ^hello 與以字串hello起始的行匹配
(8) hello$ 與以字串hello結束的行匹配
(9) \ 逸出字元,後跟特殊字元,可表示它本來的涵義
(10)
\d 匹配一個數字字元. 等價於 [0-9]
\D 匹配一個非數字元. 等價於 [^0-9]
\w ,等價於 "[A-Za-z0-9_]"
\W 匹配任何非單詞字元,等價於 "[^A-Za-z0-9]"
\s 匹配任何空白字元, 包括空格 定位字元 換頁符 等等. 等價於[\f\n\r\t\v]
\S 匹配任何非空白字元. 等價於 [^\f\r\n\t\v]
\b 匹配一個單詞邊界,也就是指單詞和空格間的位置。
\B 匹配非單詞邊界。
如,
$grep '[' filename
返回結果為grep : Invalid regular expression
而 ,
$grep '\[' filename
會匹配所有包含'['(不包括單引號)的行。
X\{n\} 與連續包含n個字元X的行匹配
(11) X\ {n,\} 與至少連續包含n個字元X的行匹配 (注意n後面的',')
(12) X \{,m\} 與最多連續包含m個字元X的行匹配 (注意m前面的',')
(13) X \{n,m\} 與最少包含n個,最多包含m個字元X的行匹配
注意:
1.不要混淆shell 中的".","*"與Regex中的".","*",很多剛開始學的人都會犯錯。
在Regex中,"."很像shell中的"?",它與任意單一字元匹配。而"*"在Regex中的使用,表示"*"前面的字元可能出現0次或1次或多次,與shell中的"*"涵義不同。
2.grep 中模式(pattern)之間的OR,AND,NOT 操作
1.grep or 操作(4 種方法)
1.1 使用 \|
$grep 'pattern1\|pattern2' filename
1.2.使用 -E 選項
grep -E 代表擴充的Regex. 若使用-E選項,則可以去掉逸出字元'\',直接使用'|'
$grep -E 'pattern1|pattern2' filename
1.3.使用 egrep 命令
egrep 相當於 ‘grep -E’.
1.4.使用 -e 選項
通過指定多個-e選項來應用多個pattern,多個pattern之間是“或”的關係
$grep -e pattern1 -e pattern2 filename
2.grep AND 操作
2.1 使用 -E選項和模式字元 'pattern1.*pattern2'
$grep -E 'pattern1.*pattern2' filename
以上命令為在filename檔案中尋找既與pattern1匹配又與pattern2匹配的行
$grep -E 'pattern1.*pattern2|pattern2.*pattern1' filename
2.2 利用管道實現
$grep -E 'pattern1' filename | grep -E 'pattern2'
3.Grep NOT 操作
3.1使用 -v 選項
$grep -v 'pattern' filename
以上命令在filename檔案中尋找不能與pattern匹配的行
Part 3 grep命令的 Examples
1. 對檔案中的空行計數
$grep -c "^$" filename
2.尋找在“hello”有任意長度字串的行
$grep ".*hello" filename
3.尋找在'hi'與'hello'之間至少有一個空格的行
$grep "hi \+hello" filename
4.尋找在'hi'與'hello'之間沒有空格或有多個空格的行
$grep "hi *hello" filename
5..尋找在'hi'與'hello'之間沒有空格或有1個空格的行
$grep "hi \?hello" filename
6.尋找ip地址127.0.0.1 (其中包含特殊字元 '.')
$grep "127\.0\.0\.1" filename
7.過濾其他命令的輸出結果
$ls --help | grep "dired"
將ls命令的協助文本,作為grep的輸入,尋找與"dired"匹配的行
輸出為:-D, --dired generate output designed for Emacs' dired mode
8.從系統日誌中獲得有用的資訊
在apache記錄檔中尋找以IP地址開頭,包含數字200的行
$grep -Eoc "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}.* 200" /srv/www/example.com/logs/access.log
References:
[1]How To Use Linux Grep Command To Find Strings
http://www.expertslogin.com/linux-administration/linux-grep-command-find-strings/
[2]Grep command in Linux explained Guide Discover grep and never lose anything again
http://www.techradar.com/news/software/operating-systems/grep-command-in-linux-explained-699455
[3] Search and Filter Text with Grep http://library.linode.com/linux-tools/common-commands/grep
[4] Linux / Unix Command: grep http://linux.about.com/od/commands/l/blcmdl1_grep.htm
[5] Regular Expressions in Grep Command with 10 Examples
http://www.thegeekstuff.com/2011/01/regular-expressions-in-grep-command/
[6] Using grep http://www.linuxjournal.com/article/1149?page=0,1
[7]15 Practical Grep Command Examples In Linux / UNIX (很豐富實用的舉例)
http://www.thegeekstuff.com/2009/03/15-practical-unix-grep-command-examples/
(The Geek Stuff 是個很不錯的linux部落格)
[8]7 Linux Grep OR, Grep AND, Grep NOT Operator Examples
http://www.thegeekstuff.com/2011/10/grep-or-and-not-operators/
[9]HowTo:Use Grep Command in Linux/Unix[examples]
http://www.cyberciti.biz/faq/howto-use-grep-command-in-linux-unix/
[10]Advanced Regular Expressions in Grep Command with 10 Examples – Part II
(更進階別的Regex)
http://www.thegeekstuff.com/2011/01/advanced-regular-expressions-in-grep-command-with-10-examples-%E2%80%93-part-ii/
[11]詳細介紹Linux grep指令 http://os.51cto.com/art/200912/168882.htm
[12] 關於Linux Grep命令使用的詳細介紹
http://fanqiang.chinaunix.net/system/linux/2007-03-15/5110.shtml
轉載本文請註明作者和出處[Gary的影響力]http://garyelephant.me,請勿用於任何商業用途!
Author: Gary Gao 關注互連網、分布式、高並發、自動化、軟體團隊