Linux提取命令grep 有這一篇就夠了

跡憶客發表於2021-12-13

grep作為linux中使用頻率非常高的一個命令,和cut命令一樣都是管道命令中的一員。並且其功能也是對一行資料進行分析,從分析的資料中取出我們想要的資料。也就是相當於一個檢索的功能。當然了,grep的功能要比cut強大的多了。grep檢索的條件是多種多樣的,甚至還可以和正規表示式合作來檢索。

下面我們來看grep的用法

$ grep [選項] '字串' 檔名

 

說明:grep用法中,字串就是我們想要檢索的字串;檔名就是資料來源,也就是我們需要分析的資料。因為grep可以接受來自標準輸入的資料,所以一般情況下grep作為管道命令來使用。

首先我們來看一個例項,該例項不使用任何選項。查詢/etc/passwd 中帶有mail字串的使用者的資訊:

$ grep mail /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
# 輸出兩行結果

 

選項一

-v 這裡的v是小寫,其含義是輸出沒有匹配到的字串的那些資料

-s 不顯示錯誤資訊

-V 這裡的v是大寫,列印grep命令的資訊

看下面的例子

$ grep -v mail /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
……
# 顯示了多行資訊,唯獨沒有包含mail的那些行的資料。這個例子的結果和第一個例子的結果是相反的。

 

下面我們看-s的用法

$ grep mail /etc/passwds
grep: /etc/passwds: No such file or directory  //顯示錯誤資訊,因為我們的系統中沒有/etc/passwds這個檔案
$ grep –s mail /etc/passwds
#這時輸出的資訊是空的,因為-s限制錯誤資訊的輸出

 

-V選項沒有什麼好介紹的,就是列印我們當前系統使用的grep命令的資訊,其中包含其版本

$ grep -V
grep (GNU grep) 2.5.1
Copyright 1988, 1992-1999, 2000, 2001 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 

選項二

這組我們主要介紹對grep輸出資訊的進行控制的選項。

-m 當顯示的行數達到該選項指定的行數限制的時候即停止輸出。也就是說如果-m指定顯示行數最大為3,如果檢索出來的結果有4行,那也只顯示前三行。

$ grep mail –m 1 /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin  #只顯示一行結果,通過前面的例子我們知道其實含有mail字串的一共有兩行資料。
# or
$ grep mail –max-count=1 /etc/passwd    # -m NUM  <=> --max-count=NUM
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin //同樣結果也是一行

 

-n 在輸出被檢索到的字串的資料之前同時在前面顯示每行資料所在的行號。

$ grep mail –n /etc/passwd
9:mail: x:8:12:mail:/var/spool/mail:/sbin/nologin
22:mailnull: x:47:47::/var/spool/mqueue:/sbin/nologin
#這兩行資料是其在/etc/passwd中所在的行號

 

-b 匹配到字串的那些行所在的起始位置,該位置是以位元組為單位計算的。意思是說,在改行資料之前有230個位元組的資料,那該行的起始位置就是230。

$ grep mail –b /etc/passwd
293:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
877:mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin

 

-o 只顯示匹配的字串

$ grep mail –o /etc/passwd
mail
mail
mail
mail

 

-H 在顯示的資訊前面加上檔名作為字首,對於檢索單個檔案來說,預設情況下不用檔名作為字首。而該選項就是在前面加上檔名作為字首。

$ grep mail –H /etc/passwd
/etc/passwd:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
/etc/passwd:mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin

 

-h 該選項和-H的功能正相反,是取出檔名作為字首。該選項用於多檔案檢索的時候,因為單檔案檢索預設情況下是沒有檔名字首的。

$ grep mail /etc/passwd /etc/group
/etc/passwd:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
/etc/passwd:mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
/etc/group:mail:x:12:mail
/etc/group:mailnull:x:47:
#多檔案檢索會在每一行前面加上改行所在的檔名作為字首
#grep mail –h /etc/passwd /etc/group
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
mail:x:12:mail
mailnull:x:47:
#此時結果中就沒有檔名的字首了

 

-q 不顯示標準輸出的資訊,即使檢索到字串也不會顯示。該選項和-s有點類似,-s是將標準錯誤輸出給遮蔽掉,而該選項是遮蔽標準輸出資訊。

$ grep mail –q /etc/passwd
#結果為空
$ grep mail –q /etc/passwd /etc/passwds
grep: /etc/passwds: No such file or directory
# 我們看,對於錯誤資訊-q並不會遮蔽
$ grep mail –qs /etc/passwd /etc/passwds
# 什麼也不顯示,標準輸出和標準錯誤輸出都被遮蔽掉了

 

-c 小寫c,顯示匹配到指定字串的行數

$ grep mail –c /etc/passwd
2

 

-d ACTION 如果輸入檔案是一個目錄,我們要使用該選項後面跟上ACTION來處理。ACTION的預設值是read,表示目錄就像普通檔案一樣被讀取;如果ACTION是skip,那麼就會跳過該目錄;如果ACTION是recurse,grep就會讀取該目錄下的所有的檔案作為資料來源(相當於grep的-r選項)。針對recurse我們舉一個例子——查詢/etc目錄下的所有檔案的內容,檢索包含以mail作為開頭的行資料

$ grep ^mail –d recurse /etc
/etc/passwd:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
/etc/passwd:mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
/etc/mail/helpfile:mail MAIL From:<sender> [ <parameters> ]
/etc/mail/helpfile:mail         Specifies the sender.  Parameters are ESMTP extensions.
/etc/mail/helpfile:mail         See "HELP DSN" for details.
……
#等價於
$ grep ^mail –r /etc
#結果相同。

 

同時我們在這裡也順便介紹了-r選項的用法。還有複習-h選項的用途,因為檢索了目錄的所有檔案,所以會在每行結果前加上檔名作為字首。可以用-h去掉

$ grep ^mail –hd recurse /etc  //這裡注意 h和d的順序
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
mail    MAIL From:<sender> [ <parameters> ]
mail            Specifies the sender.  Parameters are ESMTP extensions.
mail            See "HELP DSN" for details.
mail.*                                                  -/var/log/maillog
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
mail:*:16619:0:99999:7:::
mailnull:!!:16619:0:99999:7:::
…..

 

-D ACTION 該選項和-d基本相同,只是輸入檔案是一個裝置的時候(FIFO或者socket)使用該選項,其ACTION和-d的相同,只是沒有recurse。這裡就不再舉例子。

-a 將binary 檔案以text檔案的方式檢索資料

-I 大寫的I 忽略binary檔案

查詢pdo下面所有檔案,檢索出含有main的資料。

$ grep main –a –r /software/php-5.5.23 /ext/pdo 
# pdo下面的二進位制檔案會被當做普通文字檔案來檢索  相當於–binary-files=text。
$ grep main –binary-files=text –r /software/php-5.5.23 /ext/pdo
#結果同-a相同

 

對於pdo下面的二進位制檔案會進行忽略

$ grep main –I –r /software/php-5.5.23 /ext/pdo
#相當於 –binary-files=without-match
$ grep main –binary-files=without-match –r /software/php-5.5.23 /ext/pdo
#結果同-I 相同

 

-L 同-l相反,顯示檔案內容不包含檢索字串的檔名 等價於 --files-without-match

-l 顯示包含檢索字串的資料所在的檔案的檔名 等價於 --files-with-matches

$ grep main -l -r /software/php-5.5.23/ext/ftp
/software/php-5.5.23/ext/ftp/package.xml
# 或者
$ grep main --files-with-matches -r /software/php-5.5.23/ext/ftp
# 結果同上
$ grep main –L –r /software/php-5.5.23/ext/ftp
/software/php-5.5.23/ext/ftp/php_ftp.h
/software/php-5.5.23/ext/ftp/tests/006.phpt
/software/php-5.5.23/ext/ftp/tests/ftp_exec_basic.phpt
/software/php-5.5.23/ext/ftp/tests/ftp_nb_get_large.phpt
/software/php-5.5.23/ext/ftp/tests/ftp_get_basic.phpt
….
//部分結果,所有的顯示結果中唯獨沒有/software/php-5.5.23/ext/ftp/package.xml這個檔案
# 或者
$ grep main --files-without-match –r /software/php-5.5.23/ext/ftp

 

-A NUM在檢索到的結果後面新增NUM行資料,這些資料就是目標行資料下面挨著的NUM行資料

-B NUM 同-A相反,是在結果前面新增NUM行資料

-C NUM 在結果前後都新增NUM行資料

$ grep mail –B 1 /etc/passwd
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
--
rpc:x:32:32:Portmapper RPC user:/:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
$ grep mail –A 1 /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/etc/news:
--
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin
$ grep mail –C 1 /etc/passwd
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/etc/news:
--
rpc:x:32:32:Portmapper RPC user:/:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin

 

選項三

-i 對檢索的的字串不區分大小寫

$ grep Mail /etc/passwd
# 大寫的M檢索的結果為空,因為預設是區分大小寫的
$ grep Mail –i /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
# -i 使其不區分大小寫

 

-w 小寫的w。強制匹配整個單詞

$ grep mail –w /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
# 這時只有一行資料

 

-x 小寫的x。 強制匹配整行

$ grep mail –x /etc/passwd
# 結果為空

 

-f 指定檢索字串所在的檔案,讀取該檔案的每一行的內容作為檢索的字串。

檔案 /reg.txt

mail
nobody

 

使用該檔案作為-f指定的檔案

$ grep –f /reg.txt /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin

 

當然檔案中的內容也可以是正規表示式

例如 將內容 nobody 改成 ^nobody(以nobody開頭)

$ grep –f /reg.txt /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin

 

我們看到結果中少了一條資料。

-E 指定檢索的字串為正規表示式模式

$ grep mail /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
$ grep ‘(mail)’ /etc/passwd
#結果為空 這裡grep將’(mail)’作為一個字串來進行檢索,檢索到的結果為空
$ grep –E ‘(mail)’ /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
#使用-E 指定’(mail)’為正規表示式,所以檢索出來兩條資料

 

-e 指定字串作為查詢內容的檢索條件,其不一樣的地方是可以指定多個。

$ grep mail nobody /etc/passwd   #我們的原意是想在passwd中檢索mail和nobody
grep: nobody: No such file or directory
/etc/passwd:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
/etc/passwd:mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
//但是我們看報錯了,這時我們可以用-e來指定
$ grep –e mail –e nobody /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin

 

我們看結果已經出來了。是不是很好用

-G 指定檢索條件是一個基本的正規表示式

-P 指定檢索的條件是perl正規表示式

通過對grep命令的介紹,我們可以看到,其實grep命令之所以強大,和它支援正規表示式是分不開的,所以說熟悉正規表示式是很重要的。

相關文章