Grep 高效用法實戰總結 - 運維筆記

 

grep(global search regular expression(RE) and print out the line,全面搜索正則表達式並把行打印出來)是一種強大的文本搜索工具,能使用正則表達式搜索文本,並把匹配的行打印出來。grep主要做用是過濾出指定的行,指定的行知足什麼條件,知足的條件可配合正則表達式來表示,實現強大的文本處理。php

文本處理工具分類
經常使用的有:grep,egrep,fgrep。html

三者區別
grep: 在沒有參數的狀況下,只輸出符合RE(Regular Expression)字符。
egrep:等同於grep -E,和grep最大的區別就是表如今轉義符上, 好比grep 作次數匹配時\{n,m\}, egrep則不須要直接{n,m}。egrep顯得更方便簡潔。
fgrep:等同於grep -f,可是不能使用正則表達式。全部的字符匹配功能均已消失。linux

grep格式
grep [option] pattern filenamegit

grep的option選項說明面試

grep的option選項說明:
--color   顯示顏色的參數,即搜索出來的關鍵字符帶有顏色。使用"grep --color 關鍵字符" 或者 "grep --color=auto 關鍵字符"。通常配置別名alias grep="grep --color"
-a   不要忽略二進制數據。使用"grep -a 關鍵字符"
-A   顯示符合關鍵字符的行, 以及其後面的n行。使用 "grep -An 關鍵字符" 或者 "grep -A n 關鍵字符"
-b   顯示符合關鍵字符的行, 以及其先後的各n行。使用"grep -bn 關鍵字符", 注意這個不能使用"grep -b n 關鍵字符"! 跟-C參數差很少,可是會多打印出行號!!!
-B   顯示符合關鍵字符的行, 以及其前面的n行。 使用 "grep -An 關鍵字符" 或者 "grep -A n 關鍵字符"
-c   只輸出匹配行的計數。即只顯示出匹配關鍵字符的那行的行數,不顯示內容!使用"grep -c 關鍵字符"
-C   顯示符合關鍵字符的行, 以及其先後的各n行。使用 "grep -Cn 關鍵字符" 或者 "grep -C n 關鍵字符"。跟-b參數差很少,-b參數會多打印行號出來!
-d   當指定要查找的是目錄而非文件時,必須使用這項參數,不然grep命令將回報信息並中止動做。-d後面跟的是進行的動做,通常是"grep -d read"或"grep -d recure",後面會有小示例說明。
-e   指定字符串做爲查找文件內容的關鍵字符。使用"grep -e 關鍵字符"。grep -e "正則表達式" 文件
-E   將關鍵字符爲延伸的普通表示法來使用,意味着使用能使用擴展正則表達式!!一般用於知足多個條件中的其中一個條件進行搜索。使用grep -E "條件1|條件2|條件2"
-f   顯示兩個文件中相同的行。使用 "grep -f filename1 filename2 " 或者 "grep --file filename1 filename2",相等於"cat filename1 filename2|sort|uniq -d",即取交集!
-F   將關鍵字符視爲固定字符串的列表。使用"grep -F 關鍵字 filename1" 或者 "grep -F 關鍵字符 filename1 filename2 filenamen", 會顯示出來關鍵字所在的文件的列表。
-G   將關鍵字符視爲普通的表示法來使用。
-h   對多文件搜索關鍵字符時不顯示文件名,只顯示關鍵字符。使用"grep -h 關鍵字符 filename1 filename2 filenamen", 不顯示文件名,只顯示關鍵字符。
-H   對多文件搜索關鍵字符時顯示文件名和關鍵字符,跟-h參數相反。 使用"grep -H 關鍵字符 filename1 filename2 filenamen", 顯示"文件名:關鍵字符"。
-i   忽略關鍵字符的大小寫。(跟-y參數相同)。使用"grep -i"
-l   對多文件搜索關鍵字符時只顯示文件名。使用"grep -l 關鍵字符 filename1 filename2 filenamen",只顯示文件名,不顯示關鍵字符。
-L   對多文件搜索關鍵字符時,只顯示不匹配關鍵字符的文件名。使用"grep -L 關鍵字符 filename1 filename2 filenamen",只顯示不匹配關鍵字符的文件。
-n   顯示匹配關鍵字符的行號和行內容。使用"grep -n 關鍵字符 filename"
-q   不顯示任何信息。用於if邏輯判斷,安靜模式,不打印任何標準輸出。若是有匹配的內容則當即返回狀態值0。
-R/-r   此參數的效果和指定"-d recurse"參數相同。
-s   當搜索關鍵字符,匹配的文件不存在時不顯示錯誤信息。即不顯示不存在或無匹配文本的錯誤信息。 使用"grep -s 關鍵字符 filename"
-v   反轉或過濾搜索,即過濾出來那些不匹配關鍵字符的行。使用"grep -v 關鍵字符"
-w   精準搜索關鍵字符,即只顯示徹底匹配關鍵字符的行,不顯示那些包含關鍵字符的行。使用"grep -w 關鍵字符", 或者使用grep "\<關鍵字符\>",或者使用grep "\b關鍵字符\b"
-x   只顯示整行都是關鍵字符的行。使用"grep -x 關鍵字符"。
-y   忽略關鍵字符的大小寫。(跟-i參數相同)。"grep -y"。
-o   只輸出文件中匹配到的部分, 不會打印多餘的內容。
-P   使用perl的正則表達式語法,由於perl的正則更加多元化,能實現更加複雜的場景。典型用法是匹配指定字符串之間的字符。(-e或-E是匹配擴展正則表達式,-P是匹配perl正則表達式)

grep正則表達式元字符集(基本集)正則表達式

^
匹配行的開始 如:'^grep'匹配全部以grep開頭的行。
 
$
匹配行的結束 如:'grep$'匹配全部以grep結尾的行。
 
.
匹配一個非換行符的字符 如:'gr.p'匹配gr後接一個任意字符,而後是p。
 
*
匹配零個或多個先前字符 如:'*grep'匹配全部一個或多個空格後緊跟grep的行。 .*一塊兒用表明任意字符。
 
[]
匹配一個指定範圍內的字符,如'[Gg]rep'匹配Grep和grep。即[mn]表示匹配m或者n關鍵字符,至關於grep -E "m|n"。注意[]裏面不要放太多關鍵字符,容易混亂!只要放[]裏面的都是要匹配的關鍵字符!
 
[^]
匹配一個不在指定範圍內的字符,如:'[^A-FH-Z]rep'匹配不包含A-F和H-Z的一個字母,可是包含rep而且rep不在開頭(即*req)的行。
 
\(..\)
標記匹配字符,如'\(love\)',love被標記爲1。
 
\<
匹配單詞的開始,如:'\
 
\>
匹配單詞的結束,如'str\>'匹配包含以str結尾的單詞的行。一般使用"\<關鍵字符\>"做爲精準匹配,至關於grep -w
 
x\{m\}
重複字符x,m次,如:'o\{5\}'匹配包含5個o的行。
 
x\{m,\}
重複字符x,至少m次,如:'o\{5,\}'匹配至少有5個o的行。
 
x\{m,n\}
重複字符x,至少m次,很少於n次,如:'o\{5,10\}'匹配5--10個o的行。
 
\w
匹配文字和數字字符,也就是[A-Za-z0-9],如:'G\w*p'匹配以G後跟零個或多個文字或數字字符,而後是p。
 
\W
\w的反置形式,匹配一個或多個非單詞字符,如點號句號等。
 
\b
單詞鎖定符,如: \byang\b 表示只匹配yang。至關於grep -w "yang" 或者 grep "\<yang\>"

+
匹配一個或多個先前的字符。如:'[a-z]+able',匹配一個或多個小寫字母后跟able的串,如loveable,enable,disable等。注意:先前字符必須使用()或[]括起來,而且使用grep -E。
 
?
匹配零個或一個先前的字符。如:'(gr)?p'匹配gr後跟一個或沒有字符,而後是p的行。注意:先前字符必須使用()或[]括起來,而且使用grep -E。
 
a|b|c
匹配a或b或c。如grep -E "a|b|c", 匹配a或b或c中的任意一個均可以。grep -v "a\|b\|c" 或 egrep -v "a|b|c" 過濾掉a或b或c中的任意一個進行搜索。
 
()
分組符號,如:love(able|rs)ov+匹配loveable或lovers,匹配一個或多個ov。


=========================================================================
幾個小示例:
[root@ss-server ~]# cat sys.list 
AFG
AFS
BAU
CdC
000823
ERU
jNNNA
IFI
entegor
jKL
NNN
MYSQL
QQQ
UUU
CCS
ONLINE
MPB
IFF

以下,"A.."表示以A開頭,後面跟兩個單個字符。"."表示任意單個字符。
[root@ss-server ~]# cat sys.list |grep "A.."  
AFG
AFS

重複N字母,至少重複了3次。
[root@ss-server ~]# cat sys.list|grep "N\{3\}"
jNNNA
NNN

若是匹配正則表達式,效果以下:
[root@ss-server ~]# cat sys.list|grep "^[A-Z]\{6\}"   #至少連續出現6次大寫的字母
ONLINE
[root@ss-server ~]# cat sys.list|grep "^[A-Z]\{6,6\}"
ONLINE
[root@ss-server ~]# cat sys.list|grep "^[A-Z]\{5\}"  
MYSQL
ONLINE
[root@ss-server ~]# cat sys.list|grep "^[A-Z]\{5,6\}"
MYSQL
ONLINE
[root@ss-server ~]# cat sys.list|grep "^[A-Z]\{3\}"  
AFG
AFS
BAU
ERU
IFI
NNN
MYSQL
QQQ
UUU
CCS
ONLINE
MPB
IFF
[root@ss-server ~]# cat sys.list|grep "^[A-Z]\{3,3\}"
AFG
AFS
BAU
ERU
IFI
NNN
MYSQL
QQQ
UUU
CCS
ONLINE
MPB
IFF

POSIX字符類   (注意使用的時候,外面要套一層中括號才能生效)
爲了在不一樣國家的字符編碼中保持一致,POSIX(The Portable Operating System Interface)增長了特殊的字符類,如[:alnum:]是A-Za-z0-9的另外一個寫法。要把它們放到[]號內才能成爲正則表達式,如[A- Za-z0-9]或[[:alnum:]]。在linux下的grep除fgrep外,都支持POSIX的字符類。redis

[:alnum:]
文字數字字符。使用 grep [[:alnum:]] filename 表示打印filename文件中包括數字和字母(大小寫字母)的行

[:alpha:]
文字字符。使用 grep [[:alpha:]] filename 表示打印filename文件中包括字母(大小寫字母)的行。

[:digit:]
數字字符。使用 grep [[:digit:]] filename 表示打印filename文件中包括數字的行。

[:graph:]
非空字符(非空格、控制字符)

[:lower:]
小寫字符。使用 grep [[:lower:]] filename 表示打印filename文件中包括小寫字母的行。

[:cntrl:]
控制字符

[:print:]
非空字符(包括空格)

[:punct:]
標點符號

[:space:]
全部空白字符(新行,空格,製表符)。例如使用 sed -i 's/[[:space:]]//g' filename 表示刪除filename文件中全部的空格。

[:upper:]
大寫字符。 使用 grep [[:upper:]] filename 表示打印filename文件中包括大寫字母的行。

[:xdigit:]
十六進制數字(0-9,a-f,A-F)

grep引號使用問題spring

單引號:
即將單引號中內容原樣輸出,也就是單引號''是全引用。

雙引號: 
若是雙引號的內容中有命令、變量等,會先把變量、命令解析成結果,再將結果輸出。雙引號""是部分引用。

單雙引號:
常量用單引號''括起,而含有變量則用雙引號""括起。單雙可同時出現,單擴住雙。

"" 號裏面遇到$,\等特殊字符會進行相應的變量替換
'' 號裏面的全部字符都保持原樣

對於字符串,雙引號和單引號二者相同, 匹配模式也大體相同, 但有一些區別很是容易混淆, 例如:
grep "$a" file    #引用變量a,查找變量a的值。雙引號識別變量。
grep '$a' file    #查找"$a"字符串。單引號不識別變量。

grep "\\" file    #grep: Trailing backslash(不知緣由)
grep '\\' file    #查找‘\’字符

$  美圓符
\  反斜槓
`  反引號
" 雙引號
這四個字符在雙引號中是具備特殊含義的,其餘都沒有,而單引號使全部字符都失去特殊含義!

若是用雙引號,查找一個\,就應該用四個\:
grep "\\\\" file 這樣就對了,這樣等同於:
grep '\\' file

第一條命令shell把四個\,轉義成2個\傳遞給grep,grep再把2個\轉義成一個\查找;
第二條命令shell沒轉義,直接把2個\傳遞給grep,grep再把2個\轉義成一個\查找;
其實grep執行的是相同的命令。

grep -E 與 grep -P區別  [ 正則中的 ?= 、?<= 、?! 、?<! ]sql

grep -E  主要是用來支持擴展正則表達式,好比 | 符號,用於grep多條件查詢,並不是是使用標準正則表達式。
grep -P  主要讓grep使用perl的正則表達式語法,由於perl的正則更加多元化,能實現更加複雜的場景。最典型的用法是"匹配指定字符串之間的字符"。

示例以下:
打印test.file文件中含有2018 或 2019 或 2020字符串的行
[root@localhost ~]# grep -E "2018|2019|2020" test.file

以下想在一句話"Hello,my name is kevin" 中匹配中間的一段字符串 "my name is",能夠這樣寫正則表達式:
[root@localhost ~]# echo "Hello,my name is kevin"
Hello,my name is kevin
[root@localhost ~]# echo "Hello,my name is kevin"|grep -P '(?<=Hello)'
Hello,my name is kevin
[root@localhost ~]# echo "Hello,my name is kevin"|grep -P '(?<=Hello).*(?= kevin)' 
Hello,my name is kevin
[root@localhost ~]# echo "Hello,my name is kevin"|grep -Po '(?<=Hello).*(?= kevin)'
,my name is
[root@localhost ~]# echo "Hello,my name is kevin"|grep -P '(?<=Hello,).*(?= kevin)' 
Hello,my name is kevin
[root@localhost ~]# echo "Hello,my name is kevin"|grep -Po '(?<=Hello,).*(?= kevin)'
my name is

這裏千萬注意下:正則中的 ?= 、?<= 、?! 、?<! 四個表達的意思。結合grep使用的時候,必定要跟上-P參數,"grep -P" 表示後面跟正則表達式。
?=     表示詢問後面跟着的東西是否等於這個。
?<=    表示詢問是否以這個東西開頭。
?!     表示詢問後面跟着的東西是否不是這個。
?<!   表示詢問是否不是以這個東西開頭 。

示例:grep -P後面跟上面四種正則時,要在引號裏使用小括號進行匹配。
[root@localhost ~]# cat test.txt              
bac
ab
bb
bch
ban
[root@localhost ~]# grep -P 'b(?=a)' test.txt 
bac
ban
[root@localhost ~]# grep -P '(?<=a)' test.txt               
bac
ab
ban
[root@localhost ~]# grep -P '(?<=a)b' test.txt             
ab
[root@localhost ~]# grep -P 'b(?!a)' test.txt 
ab
bb
bch
[root@localhost ~]# grep -P '(?<!a)b' test.txt 
bac
bb
bch
ban

按照上面的思路,若是想要取得本機ip地址,能夠以下操做:
[root@localhost ~]# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.60.232  netmask 255.255.255.0  broadcast 172.16.60.255
        inet6 fe80::e825:b3ff:fef6:1398  prefixlen 64  scopeid 0x20<link>
        ether ea:25:b3:f6:13:98  txqueuelen 1000  (Ethernet)
        RX packets 22911237  bytes 4001968461 (3.7 GiB)
        RX errors 0  dropped 17058008  overruns 0  frame 0
        TX packets 670762  bytes 98567533 (94.0 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@localhost ~]# ifconfig eth0|grep -P "(?<=inet).*(?=netmask)"
        inet 172.16.60.232  netmask 255.255.255.0  broadcast 172.16.60.255
[root@localhost ~]# ifconfig eth0|grep -Po "(?<=inet).*(?=netmask)"
 172.16.60.232

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...shell

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 -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 1
a
b
--
a
b
[root@test ~]# grep "match_pattern" file_name

grep取文件中每行的前兩個字符/前2字節                                                

示例:
[root@localhost tmp]# cat test 
00c3dd43f15eafab3b0db4bdaabb3f6d91c2f9a3b88e044ddf83393dd910eb9b 
fb0772b142fe0d214c0ccfa9c7b8ed13277c35e9fce75ba1c151dd878dcda95c
d7c3167c320d7a820935f54cf4290890ea19567da496ecf774e8773b35d5f065
131f805ec7fd68d45a887e2ef82de61de0247b4eb934ab03b7c933650e854baa
322ed380e680a77f30528ba013e3a802a7b44948a0609c7d1d732dd46a9a310d
6ac240b130982ad1c3ba3188abbf18ba4e54bdd9e504ce2d5c2eff6d3e86b8dd
af40529340df51a38ca319c40e6b718f5952990b335aa703967520809061f677
a1bbb86f4147e007af7d3f7e987cf5ed3d33912bf430d8ab3528b1953225cca6
10ebb929a9def601aa26150b2dadb6eae47ad07ac399e25ace3a5c1395fb2794

[root@localhost tmp]# cat /tmp/test|grep -o "^.\{0,2\}"
00
fb
d7
13
32
6a
af
a1
10

grep同時篩選多個條件                                                                        

grep使用-E參數實現"知足多個條件中的任意一個",以下:
1)知足任意條件(word一、word2和word3之一)將匹配。
# grep -E "word1|word2|word3"  file.txt
 
grep要想實現"同時知足多個條件",須要執行多個grep過濾命令,以下:
2)必須同時知足三個條件(word一、word2和word3)才匹配。
# grep word1 file.txt | grep word2 |grep word3
# cat file.txt|grep word1 | grep word2 |grep word3
    
簡單總結下grep經常使用過濾命令:
過濾的內容能夠是一個詞組等, 須要用引號包裹
1)獲取文件中的關鍵字key:  # cat fileName | grep "key"   #即獲取fileName文件中的key字符
2)獲取文件中的某個關鍵字key1, key2, key3:   # cat fileName | grep -E "key1|key2|key3"    #即獲取fileName文件中的key1或key2或key3字符,知足一個條件便可獲取!
3)獲取文件中的多個關鍵字,同時知足:  # cat fileName | grep key1 | grep key2| grep key3    #即同時獲取fileName文件中的key1,key2和key3,必須同時知足全部條件纔可獲取!
4)忽略文件中的某個關鍵字, 須要轉義"|":   # cat fileName | grep -v "key1\|key2\|key3"     #即過濾掉fileName文件中的key1或key2或key3,知足一個條件便可過濾!
4)忽略文件中的多個關鍵字,:   # cat fileName | grep -v "key1"| grep -v "key2"| grep -v "key3"  #即過濾掉fileName文件中的key1,key2和key3,必須同時知足全部條件纔可過濾!
 
grep經常使用的還有:
grep -i:表示不區分大小寫
grep -w:精準匹配   [或者使用單字邊界"\<\>"或鎖定單詞"\b\b",即grep -w "str" 相等於 grep "\<str\>" 至關於 grep "\bstr\b"]
grep -An:獲取匹配關鍵字所在行的後n行
grep -Bn:獲取匹配關鍵字所在行的前n行
grep -Cn:獲取匹配關鍵字所在行的先後各n行

另外注意:
grep -v "條件1\|條件2\|條件3"   #須要加轉義符
egrep -v "條件1|條件2|條件3"    #不須要加轉義符
=============================================================================
示例以下:
1)排除test.txt文件中的haha、hehe字符
# cat test.txt |grep -v "haha\|hehe"
 
2)刪除/opt/data目錄下建立時間是2017年 或 2018年的文件("ls -l"命令結果中的第8列是文件建立時間、第9列是文件名。須要精準匹配)
[root@localhost ~ ]# ll
total 15996
-rw-r--r-- 1 root root   781301 Nov 11 2017 a.sql
-rw-r--r-- 1 root root   460189 Nov 11 11:20 ncc_20180909.log
-rw-r--r-- 1 root root   112055 Nov 11 23:09 data_txt
-rw-r--r-- 1 root root   730029 Nov 11 2018 gate.tar.gz
.........
 
[root@localhost ~ ]# ls -l|grep -E -w "2017|2018"|xargs rm -rf

grep精確匹配關鍵字符                                                                        
使用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
或者使用 \<\>單字邊界也能夠實現精確匹配(注意兩邊要加上雙引號)
[root@uatdns01 named]# cat /var/named/veredholdings.cn_zone|grep "\<172.16.50.24\>"
wiki02      IN     A       172.16.50.24
或者使用單詞鎖定符\b也能夠實現精確匹配
[root@uatdns01 named]# cat /var/named/veredholdings.cn_zone|grep "\b172.16.50.24\b"
wiki02      IN     A       172.16.50.24

兩個小面試題
1)精確地找出名爲abc的進程名。
# ps -ef|grep -w "abc"
或者
# ps -ef|grep "\<abc\>"
或者
# ps -ef|grep "\babc\b"
2)判斷該進程的數量是否在3-5之間。
# ps -ef|grep -w abc|wc -l
或者
# ps -ef|grep "\<abc\>"|wc -l

[[ 須要注意 ]]:grep 使用 -w 或 \<\> 或 \b 進行精準匹配時,對於@,- 特殊字符是過濾不掉的,下劃線_ 字符能夠過濾掉。
示例以下:

小示例1

寫一個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!

小示例2 

[root@localhost ABG]# ll /root/app/script/ansible/config/ABG/*.cfg|head -10
-rw-rw-rw- 1 root root 176 Aug 22 14:26 /root/app/script/ansible/config/ABG/absTag.cfg
-rw-rw-rw- 1 bxi  bxi  435 Jun 11  2019 /root/app/script/ansible/config/ABG/accounting.cfg
-rw-rw-rw- 1 root root 234 Sep  4 16:11 /root/app/script/ansible/config/ABG/accounting_springBoot.cfg
-rw-rw-rw- 1 bxi  bxi  276 Aug  7 15:21 /root/app/script/ansible/config/ABG/adapter.cfg
-rw-rw-rw- 1 bxi  bxi  359 Oct 29 14:47 /root/app/script/ansible/config/ABG/adapter-fe.cfg
-rw-rw-rw- 1 root root 191 Dec 11 15:28 /root/app/script/ansible/config/ABG/aibank-service.cfg
-rw-rw-rw- 1 root root 218 Jun 11  2019 /root/app/script/ansible/config/ABG/aicard-file.cfg
-rw-rw-rw- 1 bxi  bxi  261 Jun 11  2019 /root/app/script/ansible/config/ABG/aicard-mis.cfg
-rw-rw-rw- 1 bxi  bxi  288 Jun 11  2019 /root/app/script/ansible/config/ABG/aicard-service.cfg
-rw-rw-rw- 1 root root 177 Nov 14 09:59 /root/app/script/ansible/config/ABG/aicase.cfg

查看/root/app/script/ansible/config/ABG目錄下的cfg結尾的配置文件中是否由帶_A的配置,好比:
[root@localhost ABG]# cat /root/app/script/ansible/config/ABG/mir-x-fund.cfg
[mir-x-fund_F]
172.16.60.20

[mir-x-fund_A]
172.16.60.22

[mir-x-fund:children]
mir-x-fund_F
mir-x-fund_A

[mir-x-fund:vars]
deploy_path=/opt/ABG/mir-x-fund/
start_time_out=90
stop_time_out=60
module=mir-x-fund

[root@localhost ABG]# cat /root/app/script/ansible/config/ABG/mir-x-fund.cfg|grep -w "*_A" 
[root@localhost ABG]# cat /root/app/script/ansible/config/ABG/mir-x-fund.cfg|grep -w ".*_A"
[mir-x-fund_A]
mir-x-fund_A

腳本以下(主要用到grep -w ".*_A"):
[root@localhost ABG]# cat /root/ABG_A_file.sh 
#!/bin/bash
for file in $(ls /root/app/script/ansible/config/ABG/*.cfg)
do
   cat ${file}|grep -w ".*_A" >/dev/null 2>&1
   if [ $? -ne 0 ];then
      echo -e "ABG的$(echo ${file}|awk -F"/" '{print $NF}'|awk -F".cfg" '{print $1}')沒有A環境的配置。\n配置文件爲${file}\n"
   fi
done

執行腳本(配置文件是"應用模塊.cfg", ABG系統下的應用模塊):
[root@localhost ABG]# sh /root/ABG_A_file.sh
ABG的accounting_springBoot沒有A環境的配置。
配置文件爲/root/app/script/ansible/config/ABG/accounting_springBoot.cfg

ABG的aibank-service沒有A環境的配置。
配置文件爲/root/app/script/ansible/config/ABG/aibank-service.cfg

ABG的aireader-service沒有A環境的配置。
配置文件爲/root/app/script/ansible/config/ABG/aireader-service.cfg

ABG的backend-aiprogram-gateway沒有A環境的配置。
配置文件爲/root/app/script/ansible/config/ABG/backend-aiprogram-gateway.cfg

ABG的backend-transation沒有A環境的配置。
配置文件爲/root/app/script/ansible/config/ABG/backend-transation.cfg

ABG的backend-visitorguide沒有A環境的配置。
配置文件爲/root/app/script/ansible/config/ABG/backend-visitorguide.cfg

ABG的code沒有A環境的配置。
配置文件爲/root/app/script/ansible/config/ABG/code.cfg

grep高效搜索用法大全                                                                       

下面以/opt/aa.txt文件搜索爲例
[root@ss-server ~]# cat /opt/aa.txt
beijing
beihai
this is test
you are good
   
經過管道過濾ls -l輸出的內容,只顯示以a開頭的行。
[root@ss-server ~]# ls -l | grep '^a'
   
顯示全部以d開頭的文件中包含test的行。
[root@ss-server ~]# grep 'test' d*
   
顯示在aa,bb,cc文件中匹配test的行。
[root@ss-server ~]# grep 'test' aa bb cc
   
顯示aa文件中全部包含每一個字符串至少有5個連續小寫字符的字符串的行。
[root@ss-server ~]# grep '[a-z]\{5\}' aa
   
可以使用-o僅僅打印匹配的字符
[root@ss-server ~]# echo this is line. |grep -o "[a-z]*.$"
line.
[root@ss-server ~]# echo this is line. |grep -o "[a-z]*\."
line.
[root@ss-server ~]# grep -o "bei" /opt/aa.txt
bei
bei
   
打印除匹配行以外的其它行,使用-v:
[root@ss-server ~]# echo -e "1\n2\n3\n4"|grep -v "1\|2\|3"
4
[root@ss-server ~]# grep -v "beihai\|this is test" /opt/aa.txt
beijing
you are good
   
統計匹配字符串的行數。使用-c
[root@ss-server ~]# echo -e "1\n2\n3\n4"|grep -v "1\|2" -c
2
   
統計字符串模式匹配的次數。可以結合-o。
[root@ss-server ~]# echo "beijing is good"|grep -o "bei"
bei
[root@ss-server ~]# echo "beijing is good"|grep -o "i"
i
i
i
   
假設需要顯示行號,可以打開-n
[root@ss-server ~]# cat /opt/aa.txt |grep -o "bei" -n
1:bei
2:bei
   
-b選項可以打印出匹配的字符串想對於其所在的行起始位置的偏移量(從0開始)。一般配合-o使用:
[root@ss-server ~]# echo "012333456789" | grep -b -o 4
6:4
[root@ss-server ~]# echo "beijing ai ni"|grep -o "ai" -b
8:ai
[root@ss-server ~]# echo "beijing ai ni"|grep -o "jing" -b
3:jing
   
-P參數(聲明grep後面要用的是perl的正則表達式)(\d+ 一個或多個數字)
[root@ss-server ~]# echo -e "\nline.123\nline."|grep -P "[a-z]*\.\d+"
line.123
[root@ss-server ~]# echo -e "\nline.123\nline."|grep -P "[a-z]*\."
line.123
line.
[root@ss-server ~]# echo -e "\nline.123\nline."|grep -P "[a-z]*\.$"
line.
[root@ss-server ~]# echo -e "\nline.123\nline."|grep -P "\.$"
line.
   
匹配多個字符串模式(grep -e 或者 grep -E):
沒有-o參數不會只打印匹配項
添加-o參數以後只打印匹配項
[root@ss-server ~]# cat /opt/aa.txt |grep -e "bei" -e "jing" -e "test"
beijing
beihai
this is test
[root@ss-server ~]# cat /opt/aa.txt |grep -e "bei" -e "jing" -e "test" -o
bei
jing
bei
test
   
[root@ss-server ~]# grep -E "bei|jing|test" /opt/aa.txt
beijing
beihai
this is test
[root@ss-server ~]# grep -E "bei|jing|test" -o /opt/aa.txt
bei
jing
bei
test
   
參數oP一塊兒使用,會單獨打印出要匹配的數字
[root@ss-server ~]# echo office365 | grep -oP "\d+"
365
[root@ss-server ~]# echo office365 | grep -oP "\d*"
365
[root@ss-server ~]# echo office365 | grep -oP "[0-9]*"
365
[root@ss-server ~]# echo 365beijing23 | grep -oP "\d+"
365
23
[root@ss-server ~]# echo 365beijing23 | grep -oP "\d*"
365
23
[root@ss-server ~]# echo 365beijing23 | grep -oP "[0-9]*"
365
23
   
只有參數-P,會完整顯示匹配內容的一行,匹配內容高亮顯示
[root@ss-server ~]# echo office365 | grep -P "\d+"
office365
   
只有參數-o,不會匹配任何內容,由於沒有聲明grep要使用正則表達式
若是單獨使用參數-o,後面匹配的要是一個具體的字符串,不是正則
[root@ss-server ~]# echo office365 | grep -o "\d+"
[root@ss-server ~]#
[root@ss-server ~]# echo office365 | grep -o "365"
365
   
-Z選項在輸出匹配文件名稱時將以/0結尾配合xargs -0可以發揮很是多做用。
以下,將當前路徑下包括wang字符串的文件所有刪除
[root@ss-server ~]# echo "wang" >>11.txt
[root@ss-server ~]# echo "wangbo" >>12.txt
[root@ss-server ~]# echo "wanghu" >>13.txt
[root@ss-server ~]# echo "liru" >>14.txt
[root@ss-server ~]# grep -lZ "wang" *
11.txt 12.txt 13.txt
[root@ss-server ~]# grep -lZ "wang" *|xargs -0 rm
[root@ss-server ~]# ls
14.txt
   
限定全字匹配選項:-w,即精準匹配,三種方法:-w參數,"\<\>"單字邊界,"\b\b"
[root@ss-server ~]# echo "linux" >> aa.list
[root@ss-server ~]# echo "li" >> bb.list
[root@ss-server ~]# grep -rn "li" *.list
aa.list:1:linux
bb.list:1:li
[root@ss-server ~]# grep -w "li" *.list  
bb.list:li
[root@ss-server ~]# grep "\<li\>" *.list
bb.list:li
[root@ss-server ~]# grep "\bli\b" *.list  
bb.list:li
   
"grep -E" 和 egrep 效果等同
[root@ss-server ~]# cat /etc/passwd|grep -E "linan|bobo"
linan:x:1000:1000::/home/linan:/bin/bash
bobo:x:1002:1002::/home/bobo:/bin/bash
   
[root@ss-server ~]# cat /etc/passwd|egrep "linan|bobo"
linan:x:1000:1000::/home/linan:/bin/bash
bobo:x:1002:1002::/home/bobo:/bin/bash
   
"grep -e"參數一樣是匹配多個關鍵字
[root@ss-server ~]# cat /etc/passwd|grep -e "linan" -e "bobo"
linan:x:1000:1000::/home/linan:/bin/bash
bobo:x:1002:1002::/home/bobo:/bin/bash
 
#######################################################################################################################
#######################################################################################################################
grep -q : 安靜模式,不打印任何標準輸出。用於if邏輯判斷,若是有匹配的內容則當即返回狀態值0。
[root@localhost ~]# cat test.txt 
 17:41:54 up 67 days, 5 min,  2 users,  load average: 0.00, 0.01, 0.05
[root@localhost ~]# grep -q "days" test.txt
[root@localhost ~]# echo $?
0
[root@localhost ~]# grep -q "days111" test.txt
[root@localhost ~]# echo $?
1
 
[root@localhost ~]# grep -q "days" test.txt && echo ok
ok
[root@localhost ~]# grep -q "days111" test.txt && echo ok
[root@localhost ~]# grep -q "days" test.txt || echo ok    
[root@localhost ~]# grep -q "days111" test.txt || echo ok 
ok
 
"grep -i" 或 "grep -y" 不區分大小寫
[root@localhost ~]# echo -e "a\nA\nb\nc"|grep -i "a"
a
A
[root@localhost ~]# echo -e "a\nA\nb\nc"|grep -y "a"
a
A
 
grep使用正則關鍵匹配
[root@localhost ~]# cat test.txt
abc
adb123
abcde
abcdefg
[root@localhost ~]# cat test.txt|grep -e '[a-z]\{4\}'
abcde
abcdefg
[root@localhost ~]# cat test.txt|grep -e '[a-z]\{5\}'
abcde
abcdefg
[root@localhost ~]# cat test.txt|grep -e '[a-z]\{6\}'
abcdefg
  
grep查找以ab開頭的行(使用^)
[root@localhost ~]# grep "^ab" test.txt
 
grep查找以de結尾的行(使用$)
[root@localhost ~]# grep "de$" test.txt
 
grep查找空行(使用^$);查找空行及其行號
[root@localhost ~]# grep "^$" test.txt
[root@localhost ~]# grep -n "^$" test.txt
 
#######################################################################################################################
#######################################################################################################################
grep利用[]搜索集合字符
[] 表示其中的某一個字符 ,例如[ade] 表示a或d或e
[root@localhost ~]# cat test.txt
abc
adb8877
123456
[root@localhost ~]# cat test.txt|grep [8]
adb8877
[root@localhost ~]# cat test.txt|grep [a8]
abc
adb8877
[root@localhost ~]# cat test.txt|grep [85]
adb8877
123456
 
能夠用^符號作[]內的前綴,表示除[]內的字符以外的字 符。
好比搜索oo前沒有g的字符串所在的行, 使用 '[^g]oo' 做搜索字符串
[root@localhost ~]# cat haha.txt
abc
cbc
3bc
[root@localhost ~]# cat haha.txt|grep "[^a]bc"
cbc
3bc
 
[] 內能夠用範圍表示,好比[a-z] 表示小寫字母,[0-9] 表示0~9的數字, [A-Z] 則是大寫字母們。
[a-zA-Z0-9]表示全部數字與英文字符。 固然也能夠配合^來排除字符。
^ 表示行的開頭,$表示行的結尾( 不是字符,是位置)那麼'^$'就表示空行, 由於只有行首和行尾。
注意: ^和$放在[]括號內或[]括號外均可以!!!
[root@localhost ~]# grep [0-9] test.txt         #搜索包含數字的行
[root@localhost ~]# grep [a-z] test.txt         #搜索包含小寫字母的行
[root@localhost ~]# grep [a-z0-9] test.txt      #搜索包含數字和小寫字母的行
[root@localhost ~]# grep [A-Z] test.txt         #搜索包含大寫字母的行 
[root@localhost ~]# grep '^[a-z]' test.txt      #搜索以小寫字母開頭的行。或者 grep '[^a-z]' test.txt
[root@localhost ~]# grep '^[^a-zA-Z]' test.txt  #搜索開頭不是英文字母的行
[root@localhost ~]# grep '\.$' test.txt         #搜索末尾是.的行。因爲.是正則表達式的特殊符號,因此要用\轉義
 
=====================================
注意:在windows系統下生成的文本文件,換行會加上一個 ^M 字符。因此最後的字符會是隱藏的^M , 故在linux裏處理Windows下面的文本時要特別注意!
能夠用下面命令來刪除^M符號。 ^M==\r
# cat dos_file | tr -d '\r' > unix_file
 
#######################################################################################################################
#######################################################################################################################
.
匹配一個非換行符的字符。即.符號匹配單個字符,能匹配空格
如:'gr.p'匹配gr後接一個任意字符,而後是p。例如'g??d' 能夠用 'g..d' 表示。 good ,gxxd ,gabd .....都符合。
   
*
匹配零個或多個先前字符 
如:'*grep'匹配全部一個或多個空格後緊跟grep的行。
如:"aa*"表示搜索一個a以上的字符串!!! 其中第一個a必定存在,第二個a能夠有一個或多個,也能夠沒有,所以表明至少一個a!!
 
.* 一塊兒用表明任意字符
.+ 字符必須出現 1 次 
.? 字符出現 0 次或 1 次
 
[root@localhost ~]#  grep 'g..d' test.txt     #搜索
[root@localhost ~]#  grep 'ooo*' test.txt     #搜索兩個o以上的字符串!!前兩個o必定存在,第三個o可沒有,也可有多個
[root@localhost ~]#  grep 'goo*g' test.txt    #搜索g開頭和結尾,中間是至少一個o的字符串,即gog, goog....gooog...等
[root@localhost ~]#  grep 'g.*g' test.txt     #搜索g開頭和結尾的字符串在的行。 .*表示 0個或多個任意字符
 
#######################################################################################################################
#######################################################################################################################
{ }  表示限定連續重複字符的範圍
 
.* 只能限制0個或多個, 若是要確切的限制字符重複數量,就用{範圍} 。範圍是數字,用,隔開,好比2,5就表示2~5個;"2"表示2個,"2,"表示2到更多個
 
須要注意:因爲{ } 在SHELL中有特殊意義,所以做爲正則表達式用的時候要用\轉義一下。
 
[root@localhost ~]#  grep 'o\{2\}' test.txt          #搜索包含兩個o的字符串的行, 2個或2個以上的o的字符串的行都會搜索出來。'o\{2\}'其實等同於'o\{2,\}'
[root@localhost ~]#  grep 'go\{2,5\}g' test.txt      #搜索g後面跟2~5個o,後面再跟一個g的字符串的行
[root@localhost ~]#  grep 'go\{2,\}g' test.txt       #搜索包含g後面跟2個以上o,後面再跟g的行

搜索test.txt文件中包含2次bo字符串的行 (2個或2個以上的bo字符串都會被打印出來)
[root@localhost ~]# grep -n '\(bo\)\{2\}' test.txt

搜索test.txt文件中至少包含1次bo字符串的行
[root@localhost ~]# grep -n '\(bo\)\{1,\}' test.txt

搜索test.txt文件中出現1~3次包含bo字符串的行
[root@localhost ~]# grep -n '\(bo\)\{1,3\}' test.txt

顯示test.txt 文件中至少有5個連續小寫字符的字符串的行
[root@localhost ~]# grep -n '[a-z]\{5\}' test.txt
 
須要注意:
若是想讓[]括號中的^ - 不表現特殊意義,能夠放在[]裏面內容的後面。
例如:'[^a-z\.!^ -]' 表示沒有小寫字母,沒有. 沒有!, 沒有空格,沒有- 的 串,注意[]裏面有個小空格。
 
另外:shell 裏面的反向選擇爲[!range], 正則裏面是 [^range]。正則[^0-9]表示不以數字爲開頭的字符串。
 

######### grep 的標籤 ##########
格式:grep '\(str\)\(\)\(\)[other]\1' filename

[root@localhost ~]# cat -n test1.txt
     1  kevinboaakevin
     2  kevinboeekevin
     3  kevinbocccckevinaabb
[root@localhost ~]# grep -n "\(kevin\)\(bo\)..\1" test1.txt
1:kevinboaakevin
2:kevinboeekevin

[root@localhost ~]# grep 'w\(es\)t.*\1' test.txt
若是west被匹配,則es就被存儲到內存中,並標記爲1,而後搜索任意個字符(.*),這些字符後面緊跟着 另一個es(\1),找到就顯示該行。
若是用egrep或grep -E,就不用」\」號進行轉義,直接寫成'w(es)t.*\1'就能夠了。示例以下:
[root@localhost ~]# cat test.txt
westbwest
west123
westasdfwestsdf
[root@localhost ~]# grep 'w\(es\)t.*\1' test.txt
westbwest
westasdfwestsdf
[root@localhost ~]# grep -E 'w(es)t.*\1' test.txt
westbwest
westasdfwestsdf
[root@localhost ~]# egrep 'w(es)t.*\1' test.txt
westbwest
westasdfwestsdf

#######################################################################################################################
#######################################################################################################################
grep 擴展正則表達式是對基礎正則表達式添加了幾個特殊構成的。
 
例如:去除空白行和行首爲#的行
[root@localhost ~]# grep -v '^$' test.txt | grep -v '^#'  
[root@localhost ~]# egrep -v '^$|^#' test.txt  
[root@localhost ~]# grep -v '^$\|^#' test.txt
 
這裏列出幾個擴展特殊符號:
+   匹配一個或多個先前的字符。如:'[a-z]+able',匹配一個或多個小寫字母后跟able的串,如loveable,enable,disable等。注意:先前的字符必須使用()或[]括起來,而且使用grep -E。
?   匹配零個或一個先前的字符。如:'(gr)?p'匹配gr後跟一個或沒有字符,而後是p的行。注意:先前的字符必須使用()或[]括起來,而且使用grep -E。
|   表示或關係,好比 'gd|good|dog' 表示有gd,good或dog的串
()  表示將部份內容合成一個單元組。 好比 要搜索 glad 或 good 能夠這樣 'g(la|oo)d'
 
()的好處是能夠對小組使用 + ? * 等。好比要搜索A開頭和C結尾,而且中間有至少一個(xyz)的字符串,能夠這樣 'A(xyz)+C'
 
示例以下(注意要使用grep -E參數,而且先前字符使用()或[]括起來 ):
[root@localhost ~]# grep -E '(gr)?p' test.txt        #搜索匹配gr後跟零個或一個字符,而後是p的行。
[root@localhost ~]# grep -E '[gr]?p' test.txt        #搜索匹配gr後跟零個或一個字符,而後是p的行
[root@localhost ~]# grep -E "(2)?22" test.txt        #搜索匹配2後跟零個或一個字符,而後是22的行
[root@localhost ~]# grep -E "[2]?2" test.txt         #搜索匹配2後跟零個或一個字符,而後是2的行
[root@localhost ~]# grep -E '(2)+' test.txt          #搜索匹配2後跟一個或多個字符的行
[root@localhost ~]# grep -E '(22)+' test.txt         #搜索匹配22後跟一個或多個字符的行
[root@localhost ~]# grep -E '(asd)+' test.txt        #搜索匹配asd後跟一個或多個字符的行
[root@localhost ~]# grep -E 'ab|12|we' test.txt      #搜索匹配ab或12或we字符的行
[root@localhost ~]# grep -v 'ab\|12\|we' test.txt    #搜索不匹配ab或12或we字符的行 (注意|前面加轉義符)
[root@localhost ~]# egrep -v 'ab|12|we' test.txt     #搜索不匹配ab或12或we字符的行(注意|前面不加轉義符)
[root@localhost ~]# grep -E "glad|good" test.txt     #搜索 glad 或 good
[root@localhost ~]# grep -E "g(la|oo)d" test.txt     #搜索 glad 或 good
[root@localhost ~]# grep -E "g(lay)+h" test.txt      #搜索 g開頭,h結尾,而且中間有一個或多個lay字符的行。注意這裏lay是一個總體了,好比搜索出glayh,glaylayh

再看下面一例
[root@localhost ~]# cat test1.txt       
boruabcff
beibiaaacsf

nice to
meet you
123
123data
567
[root@localhost ~]# grep "1." test1.txt 
123
123data
[root@localhost ~]# grep "aa*" test1.txt      
boruabcff
beibiaaacsf
123data
[root@localhost ~]# grep "n.+" test1.txt          
[root@localhost ~]# grep -E "n.+" test1.txt    
nice to
[root@localhost ~]# echo "nb" >> test1.txt
[root@localhost ~]# grep -E "n." test1.txt
nice to
nb
[root@localhost ~]# grep -E "n.+" test1.txt          
nice to
nb
[root@localhost ~]# grep -E "n.?" test1.txt
nice to
nb

經過上面,能夠看到:
在 aa* 的時候出現了這麼多,它的意思是匹配 a 字符後面的任意多個;
在直接 n.+ 的時候並無出現 n 開頭的字符,必須加上 -E 才能顯示出;

那麼 .+ 和 .? 的區別是什麼呢?(能夠從grep打印結果的標紅字符串中看出區別) 
.+ 是所有匹配出,而 .? 只是匹配出字符 n 後面緊跟的一個字符。

接着看下下來看看 Perl 的正則表達式,grep 須要加-P參數:
.* 的貪婪匹配;
.*? 的惰性匹配。

上面兩者之間的區別在於:貪婪匹配是所有匹配到整個字符串,而惰性匹配只是匹配到 tom 這個字符串。

以下示例:經過打印結果中的標紅字體就能夠看出貪婪匹配和惰性匹配的區別
[root@localhost ~]# grep -P "kevin.*" test2.txt
kevin
kevinisgoodaiyadate
kevinbeijingshangkevin321
xiaoruiskevin
[root@localhost ~]# grep -P "kevin.*?" test2.txt
kevin
kevinisgoodaiyadate
kevinbeijingshangkevin321
xiaoruiskevin


#############  Re正則表達式的幾個總結  ###########
\    忽略正則表達式中特殊字符的原有含義 
^    匹配正則表達式的開始行 
$    匹配正則表達式的結束行 
\<   從匹配正則表達式的行開始 
\>   到匹配正則表達式的行結束 
[ ] 單個字符    如[A] 即A符合要求 ,[bB]即b或B符合要求,[abc]即a或b或c符合要求
[ - ] 範圍     如[A-Z] 即A,B,C一直到Z都符合要求 
.    有的單個字符 
*    全部字符,長度能夠爲0 

#######################################################################################################################
#######################################################################################################################
1)grep -f <範本文件> 或 grep --file=<範本文件>   
表示指定範本文件,其內容含有一個或多個範本樣式,讓grep查找符合範本條件的文件內容,格式爲每列一個範本樣式。

簡單示例:
下面命令就能夠打印出文件test2.txt中與文件test1.txt中的相同行。
[root@localhost ~]# grep -f test1.txt test2.txt
[root@localhost ~]# grep --file test1.txt test2.txt
[root@localhost ~]# grep --file=test1.txt test2.txt
至關於
[root@localhost ~]# cat test1.txt test2.txt|sort|uniq -d

可是要注意一個細節:
grep -f 參數後面做爲標準的第一個文件必定不能有空行才行!!!不然打印結果就是最後一個文件的內容!!!!

[root@localhost ~]# cat haha.txt 

123
[root@localhost ~]# cat test.txt 
123
beijing
[root@localhost ~]# grep -f test.txt haha.txt                                          
123
[root@localhost ~]# grep -f haha.txt test.txt     #grep -f後的第一個文件必定不能有空行!不然打印結果就是最後一個文件的所有內容!
123
beijing

2)grep -F 關鍵字 filename1"  表示將關鍵字符視爲固定字符串的列表。
或者 
"grep -F 關鍵字符 filename1 filename2 filenamen"   表示會顯示出來關鍵字所在的文件的列表。

[root@localhost ~]# cat test1.txt 
beijing
anhui
shanghai
shenzheng
[root@localhost ~]# cat test2.txt  
beijing
linux
kevin
[root@localhost ~]# grep -F beijing test1.txt         
beijing
[root@localhost ~]# grep -F beijing test1.txt test2.txt 
test1.txt:beijing
test2.txt:beijing

[root@localhost ~]# grep -F "anhui" test1.txt test2.txt 
test1.txt:anhui

#######################################################################################################################
#######################################################################################################################
grep指定查找範圍是目錄時必用的參數:
grep -r  表示明確要求搜索子目錄。等同於 grep -d recurse
grep -d skip  表示忽略子目錄

小示例:
遍歷當前目錄及全部子目錄查找匹配"kevin"的行,使用"grep -r"
[root@localhost ~]# grep -r "kevin" .
等同於
[root@localhost ~]# grep -d recurse "kevin" .
 
在當前目錄及全部子目錄下的txt結尾文件中查找"kevin"
須要注意:命令中*.txt必定要加上引號,表示在當前及其子目錄下;若是不加引號,則表示僅僅在當前目錄下了!!
[root@localhost ~]# grep -r kevin . --include "*.txt"
等同於
[root@localhost ~]# grep -d recurse kevin . --include "*.txt"

在當前目錄下查找包含"kevin"字符的文件,忽略當前目錄下的子目錄裏的文件。
下面命令只會對當前目錄下的文件進行查找,當前目錄下的子目錄裏的文件會忽略!
若是不加-d skip, 直接使用grep "kevin" ./* 命令,則結果中會將當前目錄的子目錄打印出來,報錯說子目錄是目錄而不是文件。以下:
[root@localhost ~]# grep -d skip "kevin" ./*
./register.yml:- hosts: kevin
./test1.txt:kevinboaakevin

[root@localhost ~]# grep "kevin" ./*        
./register.yml:- hosts: kevin
grep: ./test: Is a directory      #將當前目錄下的子目錄test做爲錯誤提示信息打印出來
./test1.txt:kevinboaakevin

利用 grep 和 find 命令查找文件內容
從根目錄開始查找全部擴展名爲.log的文本文件,並找出包含 "ERROR" 的行:
[root@localhost ~]# find / -type f -name "*.log" | xargs grep "ERROR"

從當前目錄開始查找全部擴展名爲.in的文本文件,並找出包含 "kevin_log" 的行:
[root@localhost ~]# find . -name "*.in" | xargs grep "kevin_log"
相關文章
相關標籤/搜索