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


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命令之所以強大,和它支持正則表達式是分不開的,所以說熟悉正則表達式是很重要的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM