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