grep精確匹配搜索某個單詞的用法 (附: grep高效用法小結))

 

grep(global search regular expression(RE) and print out the line,全面搜索正則表達式並把行打印出來)是一種強大的文本搜索工具,它能使用正則表達式搜索文本,並把匹配的行打印出來。php

使用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.24html

[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.24redis

====================面試時給出下面兩個簡單問題===================
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 -lshell

===============看一例grep精準匹配的shell案例===============express

寫一個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        只輸出文件中匹配到的部分。bash

========================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 -ooracle

在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 -q"用於if邏輯判斷,特別好用!-q 參數意爲安靜模式,不打印任何標準輸出。若是有匹配的內容則當即返回狀態值0。
grep -q 靜默輸出:
[root@test ~]# grep -q "test" filename
不會輸出任何信息,若是命令運行成功返回0,失敗則返回非0值。通常用於if條件測試。

以下是某個腳本中使用的"grep -q"安靜模式
#Deploy_Env參數有下劃線則對Pkg_Env和Deploy_Env從新賦值
if `echo ${Deploy_Env}|grep -q  "_"`;then
    Pkg_Env=`echo ${Deploy_Env} | awk -F'_' '{print $2}'`
    Deploy_Env=`echo ${Deploy_Env} | awk -F'_' '{print $1}'`
fi

再以下一例
[root@test ~]# if $(echo "wang_shibo"|grep -q "_");then kevin=`echo "wang_shibo"|awk -F"_" '{print $2}'`;echo ${kevin};fi
shibo

打印出匹配文本以前或者以後的行:
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 1ab--ab[root@test ~]# grep "match_pattern" file_name

相關文章
相關標籤/搜索