grep(global search regular expression(RE) and print out the line,全面搜尋正規表示式並把行列印出來)是一種強大的文字搜尋工具,它能使用正規表示式搜尋文字,並把匹配的行列印出來。
使用grep搜尋某個關鍵字時,預設搜尋出來的是所有包含該關鍵字的行,如下:
搜尋/var/named/veredholdings.cn_zone檔案中172.16.50.24所在的行,預設會把所有包括172.16.50.24所在的行列印出來。
[root@uatdns01 ~]# cat /var/named/veredholdings.cn_zone|grep 172.16.50.24
devzl-app01 IN A 172.16.50.243
devzl-app02 IN A 172.16.50.244
devzl-redis01 IN A 172.16.50.245
devzl-redis02 IN A 172.16.50.246
devzl-redis03 IN A 172.16.50.247
devzl-oracle01 IN A 172.16.50.242
wiki02 IN A 172.16.50.24
[root@uatdns01 ~]# cat /var/named/veredholdings.cn_zone|grep 172.16.50.24 --color
devzl-app01 IN A 172.16.50.243
devzl-app02 IN A 172.16.50.244
devzl-redis01 IN A 172.16.50.245
devzl-redis02 IN A 172.16.50.246
devzl-redis03 IN A 172.16.50.247
devzl-oracle01 IN A 172.16.50.242
wiki02 IN A 172.16.50.24
[root@uatdns01 ~]# cat /var/named/veredholdings.cn_zone|grep -o 172.16.50.24
172.16.50.24
172.16.50.24
172.16.50.24
172.16.50.24
172.16.50.24
172.16.50.24
172.16.50.24
要想精確地搜尋出檔案中某個單詞所在的行,而不是列印所有包括該單詞字樣的行,可以使用grep -w引數
-w(--word-regexp):表示強制PATTERN僅完全匹配字詞
[root@uatdns01 ~]# cat /var/named/veredholdings.cn_zone|grep -w 172.16.50.24
wiki02 IN A 172.16.50.24
或者使用grep "\<\>"形式也可以實現精確匹配
[root@uatdns01 named]# cat /var/named/veredholdings.cn_zone|grep "\<172.16.50.24\>"
wiki02 IN A 172.16.50.24
====================面試時給出下面兩個簡單問題===================
1)精確地找出名為abc的程式名。
ps -ef|grep -w abc
或者
ps -ef|grep "\<abc\>"
2)判斷該程式的數量是否在3-5之間。
ps -ef|grep -w abc|wc -l
或者
ps -ef|grep "\<abc\>"|wc -l
===============看一例grep精準匹配的shell案例===============
寫一個shell指令碼,檢查伺服器上的main程式在不在 [root@two002 tmp]# ps -ef|grep main root 23448 23422 0 11:40 pts/0 00:00:00 grep --color=auto main [root@two002 tmp]# ps -ef|grep main|grep -v grep|wc -l 0 [root@two002 tmp]# cat /tmp/main_check.sh #!/bin/bash NUM=$(ps -ef|grep main|grep -v grep|wc -l) if [ $NUM -eq 0 ];then echo "It's not good! main is stoped!" else echo "Don't worry! main is running!" fi 執行檢查指令碼 [root@two002 tmp]# sh -x /tmp/main_check.sh ++ grep main ++ grep -v grep ++ wc -l ++ ps -ef + NUM=2 + '[' 2 -eq 0 ']' + echo 'Don'\''t worry! main is running!' Don't worry! main is running! [root@two002 tmp]# sh /tmp/main_check.sh Don't worry! main is running! 如上發現,執行指令碼/tmp/main_check.sh的過程中,看到NUM引數值是2! 但是手動執行ps -ef|grep main|grep -v grep|wc -l的結果明明是0!! 這是由於grep匹配的問題,需要grep進行精準匹配,即"grep -w" 這就需要將main_check.sh指令碼內容修改如下: [root@two002 tmp]# cat /tmp/main_check.sh #!/bin/bash NUM=$(ps -ef|grep -w main|grep -v grep|wc -l) if [ $NUM -eq 0 ];then echo "Oh!My God! It's broken! main is stoped!" else echo "Don't worry! main is running!" fi 再次執行檢查指令碼,就正確了 [root@two002 tmp]# sh -x /tmp/main_check.sh ++ grep -w main ++ grep -v grep ++ wc -l ++ ps -ef + NUM=0 + '[' 0 -eq 0 ']' + echo 'Oh!My God! It'\''s broken! main is stoped!' Oh!My God! It's broken! main is stoped! [root@two002 tmp]# sh /tmp/main_check.sh Oh!My God! It's broken! main is stoped!
================grep選項集錦====================
-a 不要忽略二進位制資料。
-A <顯示列數> 除了顯示符合範本樣式的那一行之外,並顯示該行之後的內容。
-b 在顯示符合範本樣式的那一行之外,並顯示該行之前的內容。
-c 計算符合範本樣式的列數。
-C <顯示列數>或-<顯示列數> 除了顯示符合範本樣式的那一列之外,並顯示該列之前後的內容。
-d <進行動作> 當指定要查詢的是目錄而非檔案時,必須使用這項引數,否則grep命令將回報資訊並停止動作。
-e <範本樣式> 指定字串作為查詢檔案內容的範本樣式。
-E 將範本樣式為延伸的普通表示法來使用,意味著使用能使用擴充套件正規表示式。
-f <範本檔案> 指定範本檔案,其內容有一個或多個範本樣式,讓grep查詢符合範本條件的檔案內容,格式為每一列的範本樣式。
-F 將範本樣式視為固定字串的列表。
-G 將範本樣式視為普通的表示法來使用。
-h 在顯示符合範本樣式的那一列之前,不標示該列所屬的檔名稱。
-H 在顯示符合範本樣式的那一列之前,標示該列的檔名稱。
-i 忽略字元大小寫的差別。
-l 列出檔案內容符合指定的範本樣式的檔名稱。
-L 列出檔案內容不符合指定的範本樣式的檔名稱。
-n 在顯示符合範本樣式的那一列之前,標示出該列的編號。
-q 不顯示任何資訊。
-R/-r 此引數的效果和指定“-d recurse”引數相同。
-s 不顯示錯誤資訊。
-v 反轉查詢。
-w 只顯示全字元合的列。
-x 只顯示全列符合的列。
-y 此引數效果跟“-i”相同。
-o 只輸出檔案中匹配到的部分。
========================grep常用示例========================
1)在檔案中搜尋一個單詞,命令會返回一個包含"match_pattern"的文字行:
[root@test ~]# grep match_pattern file_name
2)在多個檔案中查詢:
[root@test ~]# grep "match_pattern" file_1 file_2 file_3 ...
3)輸出除之外的所有行 -v 選項:
[root@test ~]# grep -v "match_pattern" file_name
4)標記匹配顏色 --color=auto 選項:
[root@test ~]# grep "match_pattern" file_name --color=auto
5)使用正規表示式 -E 選項:
[root@test ~]# grep -E "[1-9]+"
或
[root@test ~]# egrep "[1-9]+"
6) 只輸出檔案中匹配到的部分 -o 選項:
[root@test ~]# echo this is a test line. | grep -o -E "[a-z]+\."
line.
[root@test ~]# echo this is a test line. | egrep -o "[a-z]+\."
line.
7)統計檔案或者文字中包含匹配字串的行數 -c 選項:
[root@test ~]# grep -c "text" file_name
8)輸出包含匹配字串的行數 -n 選項:
[root@test ~]# grep "text" -n file_name
或
[root@test ~]# cat file_name | grep "text" -n
9)多個檔案
[root@test ~]# grep "text" -n file_1 file_2
10)列印樣式匹配所位於的字元或位元組偏移:
[root@test ~]# echo gun is not unix | grep -b -o "not"
7:not
#一行中字串的字元便宜是從該行的第一個字元開始計算,起始值為0。選項 -b -o 一般總是配合使用。
11)搜尋多個檔案並查詢匹配文字在哪些檔案中:
[root@test ~]# grep -l "text" file1 file2 file3...
grep遞迴搜尋檔案
12)在多級目錄中對文字進行遞迴搜尋:
[root@test ~]# grep "text" . -r -n
.表示當前目錄。
13)忽略匹配樣式中的字元大小寫:
[root@test ~]# echo "hello world" | grep -i "HELLO"
hello
14)選項 -e 制動多個匹配樣式:
[root@test ~]# echo this is a text line | grep -e "is" -e "line" -o
is
is
line
15)也可以使用-f選項來匹配多個樣式,在樣式檔案中逐行寫出需要匹配的字元。
[root@test ~]# cat patfile
aaa
bbb
[root@test ~]# echo aaa bbb ccc ddd eee | grep -f patfile -o
在grep搜尋結果中包括或者排除指定檔案:
16)只在目錄中所有的.php和.html檔案中遞迴搜尋字元"main()"
[root@test ~]# grep "main()" . -r --include *.{php,html}
17)在搜尋結果中排除所有README檔案
[root@test ~]# grep "main()" . -r --exclude "README"
18)在搜尋結果中排除filelist檔案列表裡的檔案
[root@test ~]# grep "main()" . -r --exclude-from filelist
19)使用0值位元組字尾的grep與xargs:
#測試檔案:
[root@test ~]# echo "aaa" > file1
[root@test ~]# echo "bbb" > file2
[root@test ~]# echo "aaa" > file3
[root@test ~]# grep "aaa" file* -lZ | xargs -0 rm
20)執行後會刪除file1和file3,grep輸出用-Z選項來指定以0值位元組作為終結符檔名(\0),xargs -0 讀取輸入並用0值位元組終結符分隔檔名,然後刪除匹配檔案,-Z通常和-l結合使用。
grep靜默輸出:
[root@test ~]# grep -q "test" filename
不會輸出任何資訊,如果命令執行成功返回0,失敗則返回非0值。一般用於條件測試。
列印出匹配文字之前或者之後的行:
21)顯示匹配某個結果之後的3行,使用 -A 選項:
[root@test ~]# seq 10 | grep "5" -A 3
5
6
7
8
22)顯示匹配某個結果之前的3行,使用 -B 選項:
[root@test ~]# seq 10 | grep "5" -B 3
2
3
4
5
23)顯示匹配某個結果的前三行和後三行,使用 -C 選項:
[root@test ~]# seq 10 | grep "5" -C 3
2
3
4
5
6
7
8
24)如果匹配結果有多個,會用"--"作為各匹配結果之間的分隔符:
[root@test ~]# echo -e "a\nb\nc\na\nb\nc" | grep a -A 1
a
b
--
a
b
[root@test ~]# grep "match_pattern" file_name