如果你是一個新手,請從頭閱讀這篇文章,如果你隻是忘記了grep指令的一些常用選項,請直接檢視文章尾部的總結部分即可。
先說說grep指令能做什麼?
我們可以使用grep指令在文本中查找指定的字元串,就像你在windows中打開txt檔案,使用快捷鍵“Ctrl+F”在文本中查找某個字元串一樣,說白了,可以把grep了解成字元串查找工具。
grep是Linux中最常用的“文本處理工具”之一,grep與sed、awk合稱為Linux中的三劍客。
grep的全稱為:Global search Regular Expression Print out the line
全稱中的“Global search”為全局搜尋之意。
全稱中的“Regular Expression” 表示正規表達式
是以,從grep的全稱中可以了解到,grpe是一個可以利用“正規表達式”進行“全局搜尋”的工具,grep會在文本檔案中按照指定的正則進行全局搜尋,并将搜尋出的行列印出來。
當然,不使用正規表達式也可以使用grep,但是當grep與正規表達式結合在一起時,威力更強大。
我們先來看一個最簡單的使用示例,從最簡單的示例開始認識grep。
為了實驗友善,我們先準備一個測試檔案,檔案名為testgrep,檔案内容如下。
假設,現在我們想要從testgrep文本檔案中搜尋包含“test”字元串的行,則可以使用如下指令:
上圖中的指令表示使用grep指令,在testgrep檔案中搜尋包含“test”字元串的行,并将包含test字元串的行列印出來。于是,testgrep檔案中的第一行被列印了出來,預設情況下,grep是區分大小寫的,是以,檔案中包含大寫“TEST”的行沒有被列印出來。
grep的使用是不是很簡單,我們繼續聊。
如果我們想要在搜尋字元串的時候,不區分大小寫,應該怎樣做呢?grep很貼心,為我們準備了一個選項,使用“-i”選項,即可在搜尋時不區分大小寫,示例如下:
如上圖所示,在不區分大小寫的情況下,由于testgrep文本中第一行與第五行都包含“test”,是以,這兩行都被列印了出來。
由于testgrep文本中的内容比較少,行比較少,是以,我們能數過來,是第一行與第五行包含“test”字元,如果文本中有1000行,我們還想要知道是那行文本包含“test”字元串,則可以使用“-n”選項,表示顯示列印出的行在文本中的行号,示例如下:
如上圖所示,grep不僅将符合條件的行輸出了,同時還顯示了行号,證明testgrep文本中的第1行與第5行,在不區分大小寫的情況下,都包含字元串“test”。
在centos6中,我們使用grep在文本中搜尋出來的行雖然會被列印了出來,但是在列印這些行時,被比對到的關鍵字沒有高亮顯示,如果我們想要高亮顯示行中的關鍵字,改怎麼辦呢?我們可以使用“--color”選項,高亮顯示行中的關鍵字,示例如下:
使用"--color"與使用“--clolor=auto"的效果相同,都是表示高亮顯示關鍵字,我比較懶,習慣使用“--color”。
在centos7中,系統預設為grep指令配置了别名,是以在centos7中使用grep指令時,不用顯示的指定“--color”選項,預設就會高亮顯示被比對到的關鍵字,在centos7中使用alias指令,即可檢視到grep指令的别名,如下:
可以看到,centos7中grep指令配置的别名中,預設包含了--color選項,不用顯示指定,也可高亮顯示,是以我們也可以在centos6中借鑒這種方法:
上圖中,testgrep文本中一共又兩行包含“test”字元串,如果我們隻想知道有多少行包含指定的字元串,而不在乎那些行包含這些字元串,我們可以使用如下指令,擷取到符合條件的總行數。
沒錯,使用“-c”選項即可隻痛就符合條件的總行數,而不會列印出行。
之前的示例中,包含關鍵詞的行都會被列印出來,整行都會被列印出來,如果我們隻想看被比對到的關鍵字,不想整行都被列印出來,可以嗎?必須的,使用“-o”選項即可隻列印比對到的關鍵字,而不列印出整行,示例如下:
如上圖所示,使用“-o”選項,可以隻顯示被比對到的關鍵字,而不是将整行的内容都輸出。
但是需要主要“-o”選項會把每個比對到的關鍵字都單獨顯示在一行中進行輸出,什麼意思呢?看如下示例即可明白:
如上圖所示,當沒有使用“-o”選項時,包含“123”字元串的行都會被列印出來,當同一行包含多個“123”時,所在行會被列印出來,對應關鍵字也會高亮顯示,當使用了“-o”選項時,每個被比對到的關鍵字都會被單獨列印在一行中,如上圖所示,第三個“123”與第四個“123”都屬于第10行的文本,但是它們仍然各自獨占一行的輸出了。
其實,我們在使用grep指令搜尋文本時,往往有這種需求:在找見對應關鍵字時,同時需要顯示關鍵字附件的資訊,什麼意思呢?
我們來看一個場景,就能明白,我們建立了一個測試檔案:testgrep1,測試檔案内容如下:
假設,我們想從testgrep1檔案中找出“年齡為18”的人,我們該怎麼找呢?你可能會嘗試使用如下指令:
如上圖所示,我們是比對到了“年齡:18”的行,但是我們并不能從結果中得知年齡為18的人的姓名,因為姓名和年齡并不在一行中,那麼我們該怎麼版呢?
我們可以使用“-B”選項,顯示符合條件行之前的行,“B”有before之意,示例如下:
如上圖所示,包含字元串“年齡:18”的行被高亮輸出了,同時,符合條件的行“之前的一行”也被列印了出來,這時,我們就能從結果中得知,釋然今年18歲,聽風今年18歲。
沒錯,上例中的“-B1”選項表示顯示符合條件的行的同時還顯示之前的1行,舉一反三,“-B5”代表同時顯示之前的5行,“-B3”代表同時顯示之前的3行,“-B”選項後面必須有數字,否則會報錯。
與“-B”選項對應的選項是“-A”選項,“B”有Before之意,“-A”有After之意,聰明如你,一定已經猜到了“-A”的含義,沒錯,“-A”代表顯示符合條件的行的同時,還要顯示之後的行,“-A3”表示同時顯示符合條件行之後的3行,我就不再贅述了。
說了“-A”,說了“-B”,現在說說“-C”,“-C”選項可以了解為“-A與-B”的結合,“-C”選項表示在顯示符合條件的行的同時,也會顯示其前後的行,如“-C1”,“-C1"表示列印符合條件的行的同時,也列印出之前的一行與之後的一行,“-C”有Context之意(上下文之意),示例如下:
這樣我們就能看到“年齡是18歲”的人的所有資訊了。
有時候,我們往往需要進行所謂的“精确比對”,但是使用之前的方法似乎無法滿足我們,示例如下:
上圖中,當我們在文本中搜尋“sr”字元串的時候,“sr”、“srthink”、"123sr123"、所在的行都被比對到了,因為“srthink”中也包含了“sr”,所有也被比對到了,但是當我們想要“精确比對”sr字元串的時候,按照上例中的方法就無法做到了,所謂的精确比對,就是“sr”作為一個獨立的單詞存在,而不是包含于某個字元串中,那麼,如果有這種需求,我們怎麼辦呢?使用“-w"選項可以實作我們的需求,示例如下:
如上圖所示,隻有"sr"作為一個獨立的單詞存在的時候,才會被比對到,“sr”包含于某個字元串的時候,則不會被比對到,這就是所謂的精确比對,“-w”有word之意,表示搜尋的字元串作為一個獨立的單詞時才會被比對到。
有的時候,我們需要反向查找,比如,查找“不包含某個字元串”的行,這個時候,我們需要用到“-v”選項,示例如下:
上例表示查找出文本中不包含“sr”字元串的行。
某些場景下,我們可能想要同時從多個目标中比對,什麼意思呢?看來示例就秒懂,示例如下:
上例中,我們同時在文本中搜尋了“abc”字元串與“test”字元串,包含這兩個字元串任意一個的行都會被列印出來,沒錯,就像上圖中的示例一樣,使用“-e”選項可以同時比對多個目标,多個目标之間存在“或”關系,即比對其中的任意一個都算作比對成功。
在寫腳本時,你可能隻是想利用grep判斷文本中是否存在某個字元串,你隻關心有沒有比對到,而不關心比對到的内容,你隻關心有,或者沒有,這時,我們可以使用grep的靜默模式,示例如下:
當使用“-q”選項時,表示grep使用靜默模式,靜默模式下grep不會輸出任何資訊,無論是否比對到指定的字元串,都不會輸出任何資訊,是以,我們需要配合“echo $?”指令,檢視指令的執行狀态,如果傳回值為0,證明上一條grep指令比對到了指定的字元串,如果傳回值為1,則證明上一條grep指令沒有比對到指定的字元串,就像上圖示例中的顯示的哪樣,靜默模式下,grep沒有輸出任何資訊,當我們在testgrep文本中查找“test”字元串時,可以比對到結果,當在文本中查找“ttttttttt”字元串的時候,沒有比對到結果,是以,我們隻關心有沒有比對到指定字元串時,可以使用“-q”選項,但是需要配合“echo $?”指令檢視隻狀态。
文章開頭說了,grep可以利用正規表達式進行搜尋,但是之前的舉例中,grep都沒有使用正規表達式,隻是純粹的去查找一些字元串,這次,我們使用grep指令,配合正規表達式,來查找我們想要的目标。
比如,我們想要查找某個文本中的合法郵箱,示例如下:
眼尖的你肯定發現了,上圖中的正規表達式為擴充正規表達式,而不是基礎正規表達式,是以,在上述指令中,我使用了“-E”選項。
在使用“-E”選項時,grep才支援“擴充正規表達式”,不使用“-E”選項時,grep預設隻支援“基本正規表達式”。
不同的開發語言中,正規表達式的規則可能略有不同,我們使用grep時,可以使用“-P”選項,指明使用perl相容的正規表達式。
示例如下:
好了,grep的常用選項我們已經總結完畢,剩下需要做的就是不斷的練習了。
其實,出來grep指令,其實還要egerp指令,還要fgrep指令(fast grep) 它們有各自的特點。
grep:支援基本正規表達式
egrep:支援擴充正規表達式,相當于grep -E
fgrep:不支援正規表達式,隻能比對寫死的字元串,但是速度奇快,效率高,fastgrep
總結:
為了友善以後回顧,将grep的常用選項總結如下:
--color==auto或者--color:
表示對比對到的文本着色顯示
-i:在搜尋的時候忽略大小寫
-n:
顯示結果所在的行号
-c:
統計比對到的行數,注意,是比對到的總行數,不是比對到的次數
-o: 隻顯示符合條件的字元串,但是不是整行顯示,每個符合條件的字元串單獨顯示一行
-v:輸出不帶關鍵字的行(反向查詢,反向比對)
-w:比對整個單詞,如果是字元串中包含這個單詞,則不比對
-Ax:
在輸出的時候包含結果所在行之後的指定行數,這裡隻之後的x行,A:after
-Bx:在輸出的時候包含結果所在行之前的指定行數,這裡隻之前的x行,B:before
-Cx:在輸出的時候包含結果所在行之前和之後的指定行數,這裡指之前和之後的x行,C:context
-e:實作多個選項的比對,邏輯or關系
-q:靜默模式,不輸出任何資訊,當我們隻關心有沒有比對到,缺不關心比對到什麼内容時,我們可以使用次指令,然後,使用“echo$?”檢視是否比對到,0表示比對到,1表示沒有比對到。
-P:表示使用相容perl的正則引擎
-E:使用擴充正規表達式,而不是基本正規表達式,在使用“-E”選項時,相當于使用egrep