Grep詳解

如果你是一個(gè)新手,請(qǐng)從頭閱讀這篇文章,如果你只是忘記了grep命令的一些常用選項(xiàng),直接查看文章尾部的總結(jié)部分即可。


先說說grep命令能做什么?

我們可以使用grep命令在文本中查找指定的字符串,就像你在windows中打開txt文件,使用快捷鍵 "Ctrl+F" 在文本中查找某個(gè)字符串一樣,說白了,可以把grep理解成字符查找工具。


grep是Linux中最常用的"文本處理工具"之一,grep與sed、awk合稱為L(zhǎng)inux中的三劍客。

grep的全稱為: Global search Regular Expression and Print out the line

全稱中的"Global search"為全局搜索之意。

全稱中的"Regular Expression"表示正則表達(dá)式。

所以,從grep的全稱中可以了解到,grep是一個(gè)可以利用"正則表達(dá)式"進(jìn)行"全局搜索"的工具,grep會(huì)在文本文件中按照指定的正則進(jìn)行全局搜索,并將搜索出的行打印出來。

當(dāng)然,不使用正則表達(dá)式時(shí)也可以使用grep,但是當(dāng)grep與正則表達(dá)式結(jié)合在一起時(shí),威力更強(qiáng)大。


我們先來看一個(gè)最簡(jiǎn)單的使用示例,從最簡(jiǎn)單的示例開始認(rèn)識(shí)grep。

為了實(shí)驗(yàn)方便,我們先準(zhǔn)備一個(gè)測(cè)試文件,文件名為testgrep,文件內(nèi)容如下。

grep命令詳解


假設(shè),現(xiàn)在我們想要從testgrep文本文件中搜索包含"test"字符串的行,則可以使用如下命令

grep命令詳解

上圖中的命令表示使用grep命令,在testgrep文件中搜索包含"test"字符串的行,并將包含test字符串的行打印出來。

于是,testgrep文件中的第一行被打印了出來,默認(rèn)情況下,grep是區(qū)分大小寫的,所以,文件中包含大寫"TEST"的行沒有被打印出來。

grep的使用是不是很簡(jiǎn)單,我們繼續(xù)聊。


如果我們想要在搜索字符串的時(shí)候,不區(qū)分大小寫,應(yīng)該怎樣做呢?grep很貼心,為我們準(zhǔn)備了一個(gè)選項(xiàng),使用"-i"選項(xiàng),即可在搜索時(shí)不區(qū)分大小寫,示例如下:

如上圖所示,在不區(qū)分大小寫的情況下,由于testgrep文本中的第一行與第五行中都包含"test",所以,這兩行都被打印了出來。

由于testgrep文本中的內(nèi)容不較少、行比較少,所以,我們能數(shù)過來,是第一行與第五行包含"test"字符,如果文本中有1000行,我們還想要知道哪行文本包含"test"字符串,則可以使用"-n"選項(xiàng),表示顯示打印出的行在文本中的行號(hào),示例如下。

如上圖所示,grep不僅將符合條件的行輸出了,同時(shí)還顯示了行號(hào),證明testgrep文本中的第1行與第5行,在不區(qū)分大小寫的情況下,都包含字符串"test"。


在centos6中,我們使用grep在文本中搜索出的行雖然會(huì)被打印了出來,但是在打印這些行時(shí),被匹配到的關(guān)鍵字沒有高亮顯示,如果我們想要高亮顯示行中的關(guān)鍵字,該怎么辦呢?我們可以使用"--color"選項(xiàng),高亮顯示行中的關(guān)鍵字,示例如下

注:"--color選項(xiàng)"是長(zhǎng)選項(xiàng)

使用"--color"與使用"--color=auto"的效果相同,都表示高亮顯示關(guān)鍵字,我比較懶,習(xí)慣使用"--color"。


在centos7中,系統(tǒng)默認(rèn)為grep命令配置了別名,所以在centos7中使用grep命令時(shí),不用顯式的指定"--color"選項(xiàng),默認(rèn)就會(huì)高亮顯示被匹配到的關(guān)鍵字,在centos7中使用alias命令,即可查看到grep命令的別名,如下

可以看到,centos7中為grep命令配置的別名中,默認(rèn)包含了--color選項(xiàng),所以,不用顯示指定,也可高亮顯示。

所以,我們也可以在centos6中借鑒這種方法。

testgrep文本中一共有兩行包含"test"字符串,如果我們只想知道有多少行包含指定的字符串,而不在乎哪些行包含這些字符串,我們可以使用如下命令,獲取到符合條件的總行數(shù)。

沒錯(cuò),使用"-c"選項(xiàng)即可只統(tǒng)計(jì)符合條件的總行數(shù),而不會(huì)打印出行。


之前的示例中,包含關(guān)鍵詞的行都會(huì)被打印出來,整行都會(huì)被打印出來,如果我們只想看被匹配到的關(guān)鍵字,不想整行都被打印出來,可以嗎?必須的,使用"-o"選項(xiàng)即可只打印出匹配到的關(guān)機(jī)字,而不打印出整行,示例如下。

grep命令詳解

如上圖所示,使用"-o"選項(xiàng),可以只顯示被匹配到的關(guān)鍵字,而不是講整行的內(nèi)容都輸出。

但是需要注意,"-o"選項(xiàng)會(huì)把每個(gè)匹配到的關(guān)鍵字都單獨(dú)顯示在一行中進(jìn)行輸出,什么意思呢?看如下示例即可明白。

grep命令詳解

如上圖所示,當(dāng)沒有使用"-o"選項(xiàng)時(shí),包含"123"字符串的行都會(huì)被打印出來,當(dāng)同一行中包含多個(gè)"123"時(shí),所在行會(huì)被打印出來,對(duì)應(yīng)的關(guān)鍵字也會(huì)高亮顯示,當(dāng)使用了"-o"選項(xiàng)時(shí),每個(gè)被匹配到的關(guān)鍵字都會(huì)被單獨(dú)打印在一行中,如上圖所示,第三個(gè)"123"與第四個(gè)"123"都屬于第10行的文本,但是它們?nèi)匀桓髯元?dú)占一行的輸出了。


其實(shí),我們?cè)谑褂胓rep命令搜索文本時(shí),往往有這種需求:在找到對(duì)應(yīng)的關(guān)鍵字時(shí),同時(shí)需要顯示關(guān)鍵字附近的信息,什么意思呢?

我們來看一個(gè)場(chǎng)景,就能明白,我們新建了一個(gè)測(cè)試文件:testgrep1,測(cè)試文件內(nèi)容如下

grep命令詳解

假設(shè),我們想從testgrep1文件中找出"年齡為18"的人,我們?cè)撛趺凑夷??你可能?huì)嘗試使用如下命令。

grep命令詳解

如上圖所示,我們是匹配到了"年齡:18"的行,但是我們并不能從結(jié)果中得知年齡為18的人的姓名,因?yàn)樾彰c年齡并不在一行中,那么我們?cè)撛趺崔k呢?

我們可以使用"-B"選項(xiàng),顯示符合條件的行之前的行,"B"有before之意,示例如下

grep命令詳解

如上圖所示,包含字符串"年齡:18"的行被高亮輸出了,同時(shí),符合條件的行"之前的一行"也被打印了出來,這時(shí),我們就能從結(jié)果中得知,朱雙印今年18歲,王尼美今年18歲。

沒錯(cuò),上例中的"-B1"選項(xiàng)表示顯示符合條件的行的同時(shí)還顯示之前的1行,舉一反三,"-B5"代表同時(shí)顯示之前的5行,"-B3"代表同時(shí)顯示之前的3行,"-B"選項(xiàng)的后面必須有數(shù)字,否則會(huì)報(bào)錯(cuò)。


與"-B"選項(xiàng)對(duì)應(yīng)的選項(xiàng)是"-A"選項(xiàng),"-B"有Before之意,"-A"有After之意,聰明如你,一定已經(jīng)猜到了"-A"的含義,沒錯(cuò),"-A"代表顯示符合條件的行的同時(shí),還要顯示之后的行,"-A3"表示同時(shí)顯示符合條件的行之后的3行,我就不再贅述了。


說了"-A",說了"-B",現(xiàn)在說說"-C","-C"選項(xiàng)可以理解為"-A與-B"的結(jié)合,"-C"選項(xiàng)表示在顯示符合條件的行的同時(shí),也會(huì)顯示其前后的行,如"-C1","-C1"表示打印符合條件的行的同時(shí),也打印出之前的一行與之后的一行,"-C"有Context之意(上下文之意),示例如下。

grep命令詳解

這樣我們就能看到"年齡是18歲"的人的所有信息了。


有的時(shí)候,我們往往需要進(jìn)行所謂的"精確匹配",但是使用之前的方法似乎無法滿足我們,示例如下。

grep命令詳解

上圖中,當(dāng)我們?cè)谖谋局兴阉?zsy"字符串的時(shí)候,"zsy"、"zsythink"、"123zsy123"所在的行都被匹配到了,因?yàn)?zsythink"中也包含了"zsy",所以也被匹配到了,但是當(dāng)我們想要"精確匹配"zsy字符串的時(shí)候,按照上例中的方法就無法做到了,所謂的精確匹配,就是"zsy"作為一個(gè)獨(dú)立的單詞存在,而不是包含于某個(gè)字符串中,那么,如果有這種需求,我們?cè)趺崔k呢?使用"-w"選項(xiàng)可以實(shí)現(xiàn)我們的需求,示例如下。

grep命令詳解

如上圖所示,只有"zsy"作為一個(gè)獨(dú)立的單詞存在的時(shí)候,才會(huì)被匹配到,"zsy"包含于某個(gè)字符串的時(shí)候,則不會(huì)被匹配到,這就是所謂的精確匹配,"-w"有word之意,表示搜索的字符串作為一個(gè)獨(dú)立的單詞時(shí)才會(huì)被匹配到。


有的時(shí)候,我們需要反向查找,比如,查找"不包含某個(gè)字符串"的行,這個(gè)時(shí)候,我們需要用到"-v"選項(xiàng),示例如下。

grep命令詳解

上例表示查找出文本中不包含"zsy"字符串的行。


某些場(chǎng)景下,我們可能想要同時(shí)從多個(gè)目標(biāo)中匹配,什么意思呢?看了示例就秒懂,示例如下。

grep命令詳解

上例中,我們同時(shí)在文本中搜索了"abc"字符串與"test"字符串,包含這兩個(gè)字符串中任意一個(gè)的行都會(huì)被打印出來,沒錯(cuò),就像上圖中的示例一樣,使用"-e"選項(xiàng)可以同時(shí)匹配多個(gè)目標(biāo),多個(gè)目標(biāo)之間存在"或"關(guān)系,即匹配其中的任意一個(gè)都算作匹配成功。


在寫腳本時(shí),你可能只是想要利用grep判斷文本中是否存在某個(gè)字符串,你只關(guān)心有沒有匹配到,而不關(guān)心匹配到的內(nèi)容,你只關(guān)心有,或者沒有,這時(shí),我們可以使用grep的靜默模式,示例如下。

grep命令詳解

當(dāng)使用"-q"選項(xiàng)時(shí),表示grep使用靜默模式,靜默模式下grep不會(huì)輸入任何信息,無論是否匹配到指定的字符串,都不會(huì)輸出任何信息,所以,我們需要配合"echo $?"命令,查看命令的執(zhí)行狀態(tài),如果返回值為0,證明上一條grep命令匹配到了指定的字符串,如果返回值為1,則證明上一條grep命令沒有匹配到指定的字符串,就像上圖示例中顯示的那樣,靜默模式下,grep沒有輸出任何信息,當(dāng)我們?cè)趖estgrep文本中查找"test"字符串時(shí),可以匹配到結(jié)果,當(dāng)在文本中查找"ttttttttttttt"字符串的時(shí)候,沒有匹配到結(jié)果,所以,我們只關(guān)心有沒有匹配到指定字符時(shí),可以使用"-q"選項(xiàng),但是需要配合"echo $?"命令查看執(zhí)行狀態(tài)。


注:如果你對(duì)正則表達(dá)式還不熟悉,可以先跳過下面的示例,本博客中會(huì)對(duì)"正則表達(dá)式"進(jìn)行詳細(xì)總結(jié)。

正則表達(dá)式系列文章直達(dá)鏈接:正則表達(dá)式詳解

文章開頭說了,grep可以利用正則表達(dá)式進(jìn)行搜索,但是之前的舉例中,grep都沒有使用正則表達(dá)式,只是純粹的去查找一些字符串,這次,我們使用grep命令,配合正則表達(dá)式,來查找我們想要的目標(biāo)。

比如,我們想要查找某個(gè)文本中的合法郵箱,示例如下

grep命令詳解

眼尖的你肯定發(fā)現(xiàn)了,上圖中的正則表達(dá)式為擴(kuò)展正則表達(dá)式,而不是基礎(chǔ)正則表達(dá)式,所以,在上述命令中,我使用了"-E"選項(xiàng)。

在使用"-E"選項(xiàng)時(shí),grep才支持"擴(kuò)展正則表達(dá)式",不使用"-E"選項(xiàng)時(shí),grep默認(rèn)只支持"基本正則表達(dá)式"。


不同的開發(fā)語言中,正則表達(dá)式的規(guī)則可能略有不同,我們?cè)谑褂胓rep時(shí),可以使用"-P"選項(xiàng),指明使用perl兼容的正則表達(dá)式。

示例如下:

grep命令詳解


好了,grep的常用選項(xiàng)我們已經(jīng)總結(jié)完畢,剩下需要做的就是不斷的練習(xí)了。

其實(shí),除了grep命令,其實(shí)還有egrep命令,還有fgrep命令(fast grep),它們有各自的特點(diǎn)。


grep:支持基本正則表達(dá)式

egrep:支持?jǐn)U展正則表達(dá)式,相當(dāng)于grep -E

fgrep:不支持正則表達(dá)式,只能匹配寫死的字符串,但是速度奇快,效率高,fastgrep


總結(jié)


為了方便以后回顧,將grep的常用選項(xiàng)總結(jié)如下


--color=auto 或者 --color:表示對(duì)匹配到的文本著色顯示

-i:在搜索的時(shí)候忽略大小寫

-n:顯示結(jié)果所在行號(hào)

-c:統(tǒng)計(jì)匹配到的行數(shù),注意,是匹配到的總行數(shù),不是匹配到的次數(shù)

-o:只顯示符合條件的字符串,但是不整行顯示,每個(gè)符合條件的字符串單獨(dú)顯示一行

-v:輸出不帶關(guān)鍵字的行(反向查詢,反向匹配)

-w:匹配整個(gè)單詞,如果是字符串中包含這個(gè)單詞,則不作匹配

-Ax:在輸出的時(shí)候包含結(jié)果所在行之后的指定行數(shù),這里指之后的x行,A:after

-Bx:在輸出的時(shí)候包含結(jié)果所在行之前的指定行數(shù),這里指之前的x行,B:before

-Cx:在輸出的時(shí)候包含結(jié)果所在行之前和之后的指定行數(shù),這里指之前和之后的x行,C:context

-e:實(shí)現(xiàn)多個(gè)選項(xiàng)的匹配,邏輯or關(guān)系

-q:靜默模式,不輸出任何信息,當(dāng)我們只關(guān)心有沒有匹配到,卻不關(guān)心匹配到什么內(nèi)容時(shí),我們可以使用此命令,然后,使用"echo $?"查看是否匹配到,0表示匹配到,1表示沒有匹配到。

-P:表示使用兼容perl的正則引擎。

-E:使用擴(kuò)展正則表達(dá)式,而不是基本正則表達(dá)式,在使用"-E"選項(xiàng)時(shí),相當(dāng)于使用egrep。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容