grep是一個行編輯器,它的默認動作是搜索與給定模式匹配的行顯示到屏幕上來。它的變種程序包括egrep和fgrep。
正則表達式是用戶定義的、Linux工具用來過濾文本的模式模板。正則表達式利用元字符來表示數據流中的一個或多個字符。
正則表達式(Regual Expression,REGEXP)包括BRE和ERE兩種,BRE就是基本正則表達式,而ERE是擴展正則表達式。
grep使用的元字符是BRE,egrep使用的元字符是ERE,而fgrep不使用元字符。而這三個命令可以使用不同的選項進行互通。接下來,我們來看看grep的用法。
一、grep
1. 格式
grep [options] PATTERN [FILE...]
2. 選項
-o:只顯示匹配的行中與PATTERN相匹配的部分。
-i: 忽略PATTERN和輸入文件中大小寫的區別
-v:反選,只顯示沒有被PATTERN匹配到的行
-q:靜默模式,找到匹配的內容,則命令的執行狀態返回值爲0,否則爲非0。
-A NUM:打印緊隨匹配的行之後的下文NUM行。
-B NUM: 打印緊隨匹配的行之前的上文NUM行。
-C NUM: 打印匹配出來的行的上下文各NUM行。
二、基本正則表達式
類型 | 元字符 | 解釋 |
字符匹配 | . | 匹配任意單個字符 |
[] | 匹配指定範圍內的任意單個字符 | |
[^] | 匹配指定範圍外的單個字符 | |
匹配次數 | * | 匹配其前的字符任意次,0次,1次或者多次 |
.* | 匹配任意長度的任意字符 | |
\? | 匹配其前的字符0次或者1次,即其前面的字符可有可元 | |
\+ | 匹配其前的字符1次或者多次,即其前面的字符至少出現1次 | |
\{m\} | 匹配其前的字符m次,精確匹配 | |
\{m,n\} | 匹配其前的字符至少m次,至多n次 | |
\{0,n\} | 匹配其前的字符最多n次 | |
\{m,\} | 匹配其前的字符最少m次 | |
位置錨定 | ^ | 錨定行首,寫在模式的最左側,指定的字符串只能出現在行首 |
$ | 錨定行尾,寫在模式的最右側 | |
^PATTERN$ | 用PATTERN來匹配整行 | |
^$ | 表示空行,連空格都不能包含,不包括任意字符 | |
^[[:spaces:]]* | 表示空行或者包括空白字符的行 | |
\<PATTERN | 錨定詞首 | |
\bPATTERN | 錨定詞首 | |
PATTERN\> | 錨定詞尾 | |
\<PATTERN>\ | 精確錨定單詞 | |
分組及引用 | \(PATTERN\) | 將一個或者多個字符捆綁在一起,當作一個整體進行處理; |
分組括號中的模式匹配到的內容會被正則表達式引擎自動記錄於內部的變量中,這些變量爲: \1: 模式從左側起,第一個左括號以及與之匹配到的右括號之間的字符 \2:模式從左側起,第二個左括號以及與之匹配到的右括號之間的字符 |
三、擴展正則表達式
類型 | 元字符 | 解釋 |
字符匹配 | . | 匹配任意單個字符 |
[] | 匹配指定範圍內的任意單個字符 | |
[^] | 匹配指定範圍外的單個字符 | |
匹配次數 | * | 匹配其前的字符任意次,0次,1次或者多次 |
.* | 匹配任意長度的任意字符 | |
? | 匹配其前的字符0次或者1次,即其前面的字符可有可元 | |
+ | 匹配其前的字符1次或者多次,即其前面的字符至少出現1次 | |
{m} | 匹配其前的字符m次,精確匹配 | |
{m,n} | 匹配其前的字符至少m次,至多n次 | |
{0,n} | 匹配其前的字符最多n次 | |
{m,} | 匹配其前的字符最少m次 | |
位置錨定 | ^ | 錨定行首,寫在模式的最左側,指定的字符串只能出現在行首 |
$ | 錨定行尾,寫在模式的最右側 | |
^PATTERN$ | 用PATTERN來匹配整行 | |
^$ | 表示空行,連空格都不能包含,不包括任意字符 | |
^[[:spaces:]]* | 表示空行或者包括空白字符的行 | |
\<PATTERN | 錨定詞首 | |
\bPATTERN | 錨定詞首 | |
PATTERN\> | 錨定詞尾 | |
\<PATTERN>\ | 精確錨定單詞 | |
或 | | | 或,以|爲分隔,表示或者爲|左邊,或者爲|右邊 C|cat表示C或者cat |
分組及引用 | (PATTERN) | 將一個或者多個字符捆綁在一起,當作一個整體進行處理; |
分組括號中的模式匹配到的內容會被正則表達式引擎自動記錄於內部的變量中,這些變量爲: \1: 模式從左側起,第一個左括號以及與之匹配到的右括號之間的字符 \2:模式從左側起,第二個左括號以及與之匹配到的右括號之間的字符 |
四、 BRE和ERE的區別: 從上面的兩個表可以看出基本正則表達式和擴展正則表達式的區別,那就是擴展正則表達式在進行次數匹配和分組時的元字符不再需要\進行轉義;另外擴展正則表達式多了一個或的元字符。
五、 練習:前面提到了這麼多,一起來練習下吧。
1、顯示/proc/meminfo文件中以大寫或小寫S開頭的行;
# grep -i '^s' /proc/meminfo
# grep '^[Ss]' /proc/meminfo
# grep -E '^(S|s)' /proc/meminfo
2、顯示/etc/passwd文件中其默認shell爲非/sbin/nologin的用戶;
# grep -v "/sbin/nologin$" /etc/passwd | cut -d: -f
3、顯示/etc/passwd文件中其默認shell爲/bin/bash的用戶; 進一步:僅顯示上述結果中其ID號最大的用戶;
# grep "/bin/bash$" /etc/passwd | sort -t: -k3 -n | tail -1 | cut -d: -f1,7
4、找出/etc/passwd文件中的一位數或兩位數;
# grep "\<[0-9][0-9]\?\>" /etc/passwd
# grep "\<[0-9]\{1,2\}\>" /etc/passwd
5、顯示/boot/grub/grub.conf中以至少一個空白字符開頭的行;
# grep "^[[:space:]]\{1,\}" /boot/grub/grub.conf
6、顯示/etc/rc.d/rc.sysinit文件中,以#開頭,後面跟至少一個空白字符,而後又有至少一個非空白字符的行;
# grep "^#[[:space:]]\{1,\}[^[:space:]]\{1,\}" /etc/rc.d/rc.sysinit
7、找出netstat -tan命令執行結果中以'LISTEN'結尾的行;
# netstat -tan | grep "LISTEN[[:space:]]*$"
8、添加用戶bash, testbash, basher, nologin(SHELL爲/sbin/nologin),而找出當前系統上其用戶名和默認shell相同的用戶;
# grep "^\([[:alnum:]]\{1,\}\):.*\1$" /etc/passwd
9、擴展題:新建一個文本文件,假設有如下內容:
He like his lover.
He love his lover.
He like his liker.
He love his liker.
找出其中最後一個單詞是由此前某單詞加r構成的行。
[root@liuqing tmp]# grep "\(l..e\).*\1" love.txt
10. 顯示ifconfig命令輸出結果中的IP地址。
~]# ifconfig | grep -E -o "\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>(.\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>){3}"
六、三個命令的互換
grep -E表示使用擴展正則表達式(egrep), -F表示將模式視爲一個固定的字符串(fgrep)
egrep -G表示使用基本正則表達式(grep), -F表示將模式視爲一個固定的字符串(fgrep)
fgrep -E表示使用擴展正則表達式(egrep), -G表示使用基本正則表達式(grep)