grep 簡介 grep(Global search REgular expression and Print out the line)是Linux上的文本處理三劍客之一,另外兩個是sed和awk. grep是文本搜索工具,根據用戶指定的pattern(由文本字元及正則表達式元字元編寫的過濾條件) ...
grep簡介
grep(Global search REgular expression and Print out the line)是Linux上的文本處理三劍客之一,另外兩個是sed和awk.
grep是文本搜索工具,根據用戶指定的pattern(由文本字元及正則表達式元字元編寫的過濾條件)對目標文本逐行進行匹配檢查並列印出符合條件的行.
grep有三個版本:grep,egrep和fgrep. egrep是擴展的grep,等同於grep -E,fgrep是快速grep,不支持正則表達式.
之前覺得glob跟grep正則很相似,其實他們的區別還挺大:
glob匹配文件名,grep匹配文件內容
glob是全部匹配,grep是部分匹配
正則表達式(Regular Expression,在代碼中常簡寫為regex、regexp或RE):
正則表達式是對字元串(包括普通字元(例如,a 到 z 之間的字母)和特殊字元(稱為“元字元”))操作的一種邏輯公式,就是用事先定義好的一些特定字元、及這些特定字元的組合,組成一個“規則字元串”,這個“規則字元串”用來表達對字元串的一種過濾邏輯。正則表達式是一種文本模式,模式描述在搜索文本時要匹配的一個或多個字元串。
不同版本的grep對正則表達式的支持有所不同:
grep:預設是使用基本正則表達式(BRE)
egrep:支持擴展的正則表達式(ERE)
fgrep:不支持正則表達式(但搜索速度快)
grep命令:
命令格式:
grep [OPTIONS] PATTERN [FILE...]
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]
常用選項:
--color=auto:對匹配到的文本著色高亮顯示
-i:忽略字元大小寫
-o:僅顯示匹配到的文本自身(預設顯示匹配到的文本整行)
-v,--invert-match:顯示不能被pattern匹配到的行
-E,--extened-regexp:支持擴展的正則表達式(ERE).相當於egrep命令
-F,--fixed-strings:相當於fgrep命令
-q,--quiet,--silent:靜默模式,不輸出任何信息,取命令退出狀態碼時常用
-G,--basic-regexp:支持使用基本正則表達式
-P,--perl-regexp:支持使用pcre正則表達式(支持元字元很多)
-e PATTERN,--regexp=PATTERN:使用多模式
-f FILE,--file=:FILE為每行包含了一個pattern的文本文件,即grep script,把模式寫在一個文件里,通過讀取文件(腳本文件),來匹配
-c:顯示統計匹配到的行數
-r,--recursive:對目錄下所有文件里的內容根據模式匹配
-A #,--after-context=#:表示顯示匹配到行的後面#行
-B #,--before-context=#:表示顯示匹配到行的前面#行
-C #,-#,--context=#:表示顯示匹配到行的前後#行
示例:
# grep 'root' /etc/passwd:如果模式里有變數要用雙引號
# grep -v 'root' /etc/passwd:反向匹配,顯示所有沒有被匹配的行
# grep -i 'bash' bash.txt:忽略字元大小寫
# grep -o 'root' /etc/passwd:僅顯示匹配到的文本自身
# grep -q 'root' /etc/passwd:靜默模式
示例:
# grep -e "r..t" -e "bash" /etc/passwd:使用多模式
# grep -f /root/test/mypat /etc/passwd:使用保存在文件里的匹配模式,模式無需加引號.
# grep -A 1 "^[op]" /etc/passwd:顯示匹配到的行後面的一行
# grep -B 2 "^[op]" /etc/passwd:顯示匹配到的行前面的兩行
# grep -C 1 "^[op]" /etc/passwd:顯示匹配到的行前後各一行
基本正則表達式元字元:
1、字元匹配:
.:匹配任意單個字元
[]:匹配範圍內的任意單個字元
[^]:匹配範圍外的單個字元
[:digit:]:任意單個數字
[:lower:]:任意單個小寫字母
[:upper:]:任意單個大寫字元
[:alpha:]:任意單個字母
[:alnum:]:任意單個字母和數字
[:space:]:任意單個空白字元
[:blank:]:任意單個空格和tab
[:punct:]:任意單個標點符號
[:cntrl:]:任意單個控制符
[:graph:]:任意單個能顯示的符號
[:print:]:任意單個可列印符號
[:xdigit:]:任意單個十六進位字元
示例:
# ifconfig | grep "r..":r後跟兩個字元的行
# ifconfig | grep -i "i[a-z][a-z]":不區分大小寫,i後跟兩個字母的行
# ifconfig | grep "i[[:alpha:]][[:space:]]":i後跟一個字母再跟一個空格的行
2、次數匹配:
用在要指定其出現的次數的字元後面,用於限制其前面的字元要出現的次數,預設工作在貪婪模式
*:匹配前面的字元出現的任意次(0,1或多次)
grep "x*y":只要有y就匹配
.*:匹配任意長度的任意字元,相當於glob中的*
grep "x.*y":在x和y之間可出現任意長度任意字元即匹配
\+:匹配前面的字元至少1次(1次或多次);\為轉義符
grep "x\+y":y之前必須出現一個x
\?:匹配前面的字元0次或1次,即前面的字元可有可無
grep "x\?y":只要有y就匹配
\{m\}:匹配其前面的字元出現m次,m為非負整數
grep "x\{2\}y":y前出現2次x就匹配
\{m,n\}:匹配其前面的字元出現m次,m為非負整數;閉區間[m,n]
\{0,n\}:至多n次
因為會匹配多次,所以全部都會匹配
\{m,\}:至少m次
示例:
# ifconfig | grep "i[[:alpha:]]\{3\}":匹配i後跟3個字母的行
# ifconfig | grep "i[[:alpha:]]\{3,\}":匹配i後跟至少3個字母的行
3、位置錨定:
限制使用模式搜索文本,限制模式所匹配到的文本只能出現於目標文本的哪個位置
^:行首錨定;用於模式的最左側,^PATTERN
$:行尾錨定;用於模式的最右側,PATTERN$
^PATTERN$:要讓PATTERN完全匹配一整行
^$:匹配空行;
^[[:space:]].*$:匹配空白行;
示例:
# grep "^r..t" /etc/passwd:匹配r開頭後跟兩個字元再跟t的行
# grep "l.\{3\}n" /etc/passwd:匹配l後跟3個字元再跟n的行
# grep "l.\{3\}n$" /etc/passwd:匹配l後跟3個字元再跟n結尾的行
# grep "[[:space:]]\+" /etc/passwd:匹配至少連續出現一個空格的行
單詞:非特殊字元組成的連續字元(字元串)都稱為單詞
\<或\b:詞首錨定,用於單詞模式的左側,格式為\<PATTERN,/bPATTERN
\>或\b:詞尾錨定,用於的承諾模式的右側,格式為PATTERN\>,PATTERN\b
示例:
# grep "\<r..t" /etc/passwd:匹配單詞詞首:r後跟兩個字元再跟t的行
# grep "\<r..t\>" /etc/passwd:匹配單詞:r後跟兩個字元再跟t的行
# ifconfig | grep "\<[0-9]\{3\}\>":匹配單詞:三個數字
更多實例:
1、顯示/etc/passwd文件中不以bash結尾的行
# grep -v 'bash$' /etc/passwd
2、找出/etc/passwd文件中的三位或四位數
# grep '\<[0-9]\{3,4\}\>' /etc/passwd
3、找出/etc/grub2.cfg文件中,以至少一個空白字元開頭,後面又跟了一非空白字元的行
# grep '^[[:space:]]\+[^[:space:]]' /etc/grub2.cfg
4、找出"netstat -tan"命令的結果中,以‘LISTEN’後跟0或多個空白字元結尾的行
# netstat -tan | grep 'LISTEN[[:space:]]*$'
5、找出“fdisk -l”命令結果中,以/dev/後跟sd或hd及一個小寫字母的行
# fdisk -l | grep '/dev/[sh]d[a-z]\>'
6、找出“ldd /usr/bin/cat”命令的結果中的文件路徑
# ldd /usr/bin/cat | grep -o '/[^[:space:]]\+'
4、分組與引用:
\(PATTERN\):將此PATTERN匹配到的字元當作一個不可分割的整體進行處理
註意:分組括弧中的模式匹配到的字元會被正則表達式引擎自動記錄於內部變數中,這些變數是\1,\2,\3,...
例如:pat1\(pat2\)pat3\(pat4\(pat5)pat6\)
\n:模式中的第n個左括弧以及與之匹配的右括弧之間的模式所匹配到的字元串(不是模式,而是模式匹配的結果)
\1:表示第一組括弧總的PATTERN匹配到的的字元串;上例:pat2
\2:表示第二組括弧總的PATTERN匹配到的的字元串;上例:pat4\(pat5)pat6
\3:表示第三組括弧總的PATTERN匹配到的的字元串;上例:pat5
...
示例,文檔test內容如下:
he love his lover
he like his lover
he love his liker
he like his liker
.*l..e.*l..er
\(l..e\).*\1r
# grep -o 'l..e.*l..er' test:不能完成精確匹配
# grep -o '\(l..e\).*\1r' test:分組可完成精確匹配
後向引用:引用前面的括弧中的模式所匹配到的字元串
egrep命令:
命令格式
egrep [OPTIONS] PATTERN [FILE...]
命令選項:
egrep的選項與grep相同
擴展正則表達式的元字元:無需轉義符
字元匹配:
.:匹配任意單個字元
[]:匹配範圍內的任意單個字元
[^]:匹配範圍外的單個字元
[:digit:]:任意單個數字
[:lower:]:任意單個小寫字母
[:upper:]:任意單個大寫字元
[:alpha:]:任意單個字母
[:alnum:]:任意單個字母和數字
[:space:]:任意單個空格
[:blank:]:任意單個空格和tab
[:punct:]:任意單個標點符號
次數匹配:
*:匹配前面的字元(可有可無)出現的任意次(0,1或多次)
?:匹配前面的字元0次或1次,即前面的字元可有可無
+:匹配前面的字元至少1次(1次或多次)
{m}:匹配其前面的字元出現m次,m為非負整數
{m,n}:匹配其前面的字元出現m次,m為非負整數
{0,n}:至多n次
{m,}:至少m次
位置錨定:
^:行首錨定;用於模式的最左側,^PATTERN
$:行尾錨定;用於模式的最右側,PATTERN$
^PATTERN$:要讓PATTERN完全匹配一整行
^$:匹配空行
\<,\b:詞首錨定,用於單詞模式的左側,格式為\<PATTERN,/bPATTERN
\>,\b:詞尾錨定,用於的承諾模式的右側,格式為PATTERN\>,PATTERN\b
分組及引用:
(pattern):分組,括弧中的模式匹配到的字元會被存儲於正則表達式引擎內部的變數中
後向引用:\1,\2,\3,...
或者:
a|b:a或者b
C|cat:表示C或cat
(C|c)at:表示Cat或cat
egrep實例:
1、顯示/etc/passwd文件中不以bash結尾的行
# egrep -v 'bash$' /etc/passwd
2、找出/etc/passwd文件中的三位或四位數
# egrep '\<[0-9]{3,4}\>' /etc/passwd
3、找出/etc/grub2.cfg文件中,以至少一個空白字元開頭,後面又跟了一非空白字元的行
# egrep '^[[:space:]]+[^[:space:]]' /etc/grub2.cfg
4、找出"netstat -tan"命令的結果中,以‘LISTEN’後跟0或多個空白字元結尾的行
# netstat -tan | egrep 'LISTEN[[:space:]]*$'
5、找出“fdisk -l”命令結果中,以/dev/後跟sd或hd及一個小寫字母的行
# fdisk -l | egrep '/dev/[sh]d[a-z]\>'
# fdisk -l | egrep '/dev/(s|h)d[a-z]\>'
6、找出“ldd /usr/bin/cat”命令的結果中的文件路徑
# ldd /usr/bin/cat | egrep -o '/[^[:space:]]+'
7、找出/proc/meninfo文件中,所有以大寫或小寫s開頭的行,至少用三種方式實現
# egrep "^(s|S)" /proc/meminfo
# grep "^[sS]" /proc/meminfo
# grep -i "^s" /proc/meminfo
8、顯示當前系統上root,centos,或slackware用戶的相關信息
# egrep "^(root|centos|slackware)\>" /etc/passwd
# egrep "^(root|centos|slackware):" /etc/passwd
9、echo輸出一個絕對路徑,使用grep取出基名
# echo /etc/passwd/ | egrep -o "[^/]+/?$"
10、找出ifconfig命令結果中的1-255之間的整數
# ifconfig| egrep "\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>"
11、添加用戶bash、testbash、及nologin,要求前三個用戶的預設shell為/bin/bash,而後找出其用戶名與shell相同的用戶
# egrep "^([a-z0-9]+)\>.*\1$" /etc/passwd