grep是通用Regex解析器(General Regular Expression Parser)的縮寫。
一、grep命令的功能是分析一行資訊,若其中有我們所需要的資訊,就將其拿出來。需要注意的是它以整行為單位進行資料的選取。
文法:grep [-acinv] [--color=auto] '要尋找的字串' filename
-a:將binary檔案以text檔案的方式尋找資料
-c:計算找到尋找字串的次數
-i:忽略大小寫不同
-n:輸出行號
-v:反向選擇,顯示出沒有尋找字串的內容的行
--color-auto:將找到的字串以特殊顏色顯示
下面介紹幾個使用grep命令的執行個體。
範例:
先將/etc目錄下的manpath.config檔案拷貝至/tmp檔案夾下,來作實驗。
cd /tmp
cp/etc/manpath.config .
將此檔案中有包含MANPATH的那一行取出來。
Cat manpath.config| grep 'MANPATH'
範例:
與上例子相反,只要沒有包含MANPATH的那一行就取出來。
cat manpath.config| grep -v 'MANPATH'
二、下面介紹grep的一些進階參數。
grep [-A] [-B] [--color=auto]'尋找字串' filename'
-A:後面可加數字,為after的意思,除了列出該行以外,後續的n行也列出來。
-B:後面可加數字,為before的意思,除了列出該行以外,前面的n行也列出。
範例:
用dmesg列出核心資訊,然後用grep找出包含eth的那行,並且顯示 行號。而且將關鍵字的前2行和後3行也列出來。
Dmesg | grep -n-A3 -B2 –color=auto 'eth'
在關鍵字的顯示上,grep可以用—color=auto來將關鍵字用特殊顏色顯示。但是每次使用grep都得加上這個資訊很麻煩,於是可以用alias進行一下處理就OK了。可以在~/.bashrc內加上這一行:alias grep='grep –color=auto'。
三、下面進行一些基礎Regex的練習。
1、利用中括弧[]來尋找集合字元
比如我要尋找man或者men字串,可以這樣來尋找:
grep -n 'm[ae]n'manpath.config
Note:中括弧[]裡面不論有幾個字元,它都只代表某一個字元。
2、反向選擇^的使用
尋找包含man而且前面沒有/的那一行:
grep -n '[^/]man'manpath.config
尋找包含man但是前面不是小寫字元的那一行:
grep -n'[^a-z]man' manpath.config
要取得有數位那一行:
grep -n '[0-9]'manpath.config
考慮到語系對於編碼順序的影響,因此除了連續編碼使用減號-之外,你也可以使用如下的方法取得前面測試的結果:
grep -n'[[:digit:]]' manpath.config
關於語系編碼:
不同語系的編碼資料並不相同,所以會造成資料選取結果的區別。舉例來說,在英文大小寫編碼順序中,zh_CN.big5及C這兩種語系的輸出結果分別是:
LANG=C時:012345...ABCD...Z...abcd...z
LANG=zh_CN時:012345...aAbBcCdD...zZ。
因此在使用Regex時,需要特別留意當時環境的語係為何,否則可能會發現與別人不同的選取結果。
另外,為了避免這樣編碼所造成的英文和數位選取問題,有些特殊的符號需要我們瞭解以下。主要有下面這些:
[:alnum:]代表英文大小寫字元及數字
[:blank:]代表空格和tab按鍵
[:punct:]代表標點符號
[:space:]任何會產生空白的字元
[:alpha:]代表任何英文大小寫字元
[:digit:]代表數字
[:lower:]代表小寫字元
[:upper:]代表大寫字元
3、行首^和行尾$字元
列出行首為MANPATH_MAP的行:
grep -n'^MANPATH_MAP' manpath.config
列出開頭是大寫字元的那一行:
grep -n '^[A-Z]'manpath.config
列出開頭不是英文字母的行:
grep -n'^[^a-zA-Z]' manpath.config
Note:那個^符號在字元集合(中括弧[])之內和外面是不同的!!!在[]內面代表反向選擇,在[]外面代表定位在行首的意思。
反過來思考:我們要找出行尾結束為驚嘆號.的行:
grep -n '\.$'manpath.config
因為小數點具有特殊的意義,所以必須用逸出字元加以解除其特殊意義。
尋找出空白行:
grep -n '^$'manpath.config
4、任意一個字元.與重複字元*
在bash當中,萬用字元*可以用來代表任意(0或多個)字元,但是Regex並不是萬用字元,兩者之間是不相同的。至於Regex當中:
.:代表絕對有一個字元的意思。
*:代表重複前一個字元0到無窮多次的意思,為組合形態。
執行個體:
尋找包含一個o以上的行,需要oo*:
grep -n 'oo*'manpath.config
尋找以g開頭與以g結尾,中間至少存在一個o的行:
grep -n 'goo*g'manpath.config
5、限定連續RE字元範圍
在前面的例題中,我們可以利用.與RE字元及*來設定0到無窮多個重複字元。那如果我要限制一個範圍區間內的重複字元呢,比如要找出2-5個o的連續字串,就要用到限定範圍的字元{}了。
但是{}的符號在shell有特殊意義,因此要用到逸出字元\。
執行個體:
找出g後面有兩個到五個o後面再接一個g的字串:
grep -n '\{2,5\}g'manpath.config
如果是2個以上呢:
grep -n '\{2,\}g'manpath.config
這樣就OK了。