講grep與egrep之前,我們先要知道grep與egrep是兩種文本搜索工具。而文本搜索類工具就是根據用戶指定的“模式(pattern)”對目標文本進行過濾,顯示被模式匹配到的行。
正則表達式其定義:由一類字符書寫的模式,其中有些字符不表示字符的字面意義,而是表示控制或通配的功能;(Global search REgular expression and Print out the line.)
正則表達式分類:
基本正則表達式(grep)
擴展正則表達式(egrep)
正則表達式的語法如下:
grep [OPTION]... 'PATTERN' FILE...
--color
基本正則表達式:
字符匹配:
.: 匹配任意單個字符:
例如:我先編輯一個a.txt文檔,有如下內容:
He like his lover.
He love his lover.
He like his liker.
He love his liker.
下面可以自行在XSHELL中練習查找,不在舉例
[]:匹配指定集合中的任意單個字符
[[:digit:]], [0-9]
[[:lower:]], [a-z]
[[:upper:]], [A-Z]
[[:alpha:]], [a-zA-Z]
[[:alnum:]], [0-9a-zA-Z]
[[:space:]],所有的空白字符
[[:punct:]],所有標點符號
[^]:匹配指定集合外的任意單個字符
匹配次數:用於對其前面緊鄰的字符所能夠出現的次數作出限定
*: 匹配其前面的字符任意次,0,1或多次;
例如:用grep搜索 'x*y',則會出現:xy, xxy, xxxy, y;xxxy出現說明表達式匹配的貪婪模式,能夠儘量多的匹配
\?:匹配其前面的字符0次或1次;
例如:grep 'x\?y'
xy, xxy, y, xxxxxy, aby
\+: 匹配其前面的字符出現至少1次;
\{m\}: 匹配其前面的字符m次;
例如:grep 'x\{2\}y'
xy, xxy, y, xxxxxy, aby
\{m,n\}:匹配其前面的字符至少m次,至多n次;
例如: grep 'x\{2,4\}y'
xy, xxy, y, xxxxxxy, aby
grep 'x\{0,4\}y'
xy, xxy, y, xxxxxxxxxy, aby
grep 'x\{2,\}y'
xy, xxy, y, xxxxxy
.*: 匹配任意長度的任意字符
位置錨定:
^: 行首錨定
寫在模式的最左側[[]]
$: 行尾錨定
寫在模式的最右側
^$: 空白行
\<: 詞首錨定, 或者\b
出現在要查找的單詞模式的左側;\<char
\>:詞尾錨定, 或者\b
出現在要查找的單詞模式的右側;char\>
\<pattern\>: 匹配單詞
分組:
\(\)
後向引用:模式中,如果使用\(\)實現了分組,在某行文本的檢查中,如果\(\)的模式匹配到了某內容,此內容後面的模式中可以被引用;
\1, \2, \3
模式自左而右,引用第#個左括號以及與其匹配右括號之間的模式匹配到的內容;
grep選項:
-v: 反向選取
-o: 僅顯示匹配到內容
-i: 忽略字符大小寫
-E: 使用擴展正則表達式=egrep
-A #(數字): 匹配到的那行,加上,匹配行後面的第#行也都顯示出來;選項加在要匹配內容前後都可以
-B #:匹配到的那行,加上,匹配行前面的第#行也都顯示出來;選項加在要匹配內容前後都可以
-C #:匹配行上下#行顯示出來;選項加在要匹配內容前後都可以
練習:
1、顯示/proc/meminfo文件中以大寫或小寫S開頭的行;
grep -i '^s' /proc/meminfo
2、顯示/etc/passwd文件中其默認shell爲非/sbin/nologin的用戶;
grep -v '/sbin/nologin$' /etc/passwd /etc/passwd 有很多默認shell用戶信息等,就是/sbin/nologin$ 類的用戶在此目錄中
3、顯示/etc/passwd文件中其默認shell爲/bin/bash的用戶;
進一步:僅顯示上述結果中其ID號最大的用戶;
grep '/bin/bash$' /etc/passwd | cut -d':' -f3 | sort -nr | head -1
或:grep '/bin/bash$' /etc/passwd | cut -d':' -f3 | sort -n | tail -1
4、找出/etc/passwd文件中的一位數或兩位數;
egrep '\<([0-9]|[1-9][0-9])\>' /etc/passwd ;之所以用egrep是因爲grep中沒有或字符的用法,而egrep中有 | 的用法
或:grep '\<\([0-9]\{1,2\}\)\>' /etc/passwd
5、顯示/boot/grub/grub.conf中以至少一個空白字符開頭的行
grep '^[[:space:]]\+' /boot/grub/grub.conf
6、顯示/etc/rc.d/rc.sysinit文件中,以#開頭,後面跟至少一個空白字符,而後又有至少一個非空白字符的行;
grep '^#[[:space:]]\+[^[:space:]]\+' /etc/rc.d/rc.sysinit
7、找出netstat -tan命令執行結果中以'LISTEN'(後可有空白字符)結尾的行;
netstat -tan | grep 'LISTEN[[:space:]]*$'
8、添加用戶bash, testbash, basher, nologin(SHELL爲/sbin/nologin),而找出當前系統上其用戶名和默認shell相同的用戶;
useradd -s /sbin/nologin bash 創建其他用戶,把後面bash更改一下即可 : useradd(命令) -s(option) /sbin/nologin(option的argument) bash(argument)
解析步驟:id bash(剛添加的用戶看是否創建成功)
cat /etc/passwd ;先查看一下多少用戶、ID、SHELL等信息
egrep '\<^([[:alnum:]]+)\>.*\1$' /etc/passwd
或grep '^\(\<[[:alnum:]]\+\>\).*\1$' /etc/passwd
9、擴展題:新建一個文本文件,假設有如下內容:
He like his lover.
He love his lover.
He like his liker.
He love his liker.
找出其中最後一個單詞是由此前某單詞加r構成的行。
grep '\(\<[[:alpha:]]\+\>\).*\1r' a.txt
egrep '(\<[[:alpha:]]+\>).*\1r' m.txt
egrep及擴展的正則表達式
擴展正則表達式的元字符:
字符匹配:
.
[]
[^] :不匹配
匹配次數限定:
*
?: 匹配其前面字符0次或1次;
+:匹配其前面的字符至少1次;
{m}:匹配其前面的字符m次;
{m,n}:{m,}, {0,n}
錨定:
^
$
\<, \>: \b
分組:
()
支持後向引用:\1, \2, ...
或者:
a|b: a或者b
ab|cd:ab或者cd
grep -E 'pattern' file...
或者:egrep 'pattern' file...
練習10:顯示當前系統上root、centos或user1用戶的默認shell及用戶名;
egrep '^(root|centos|user1)' /etc/passwd | cut -d: -f1,7
若用戶沒有,創建用戶 useradd 用戶名;如果加錯用戶名,修改,usermod 正確用戶名 錯誤用戶名
練習11:找出/etc/rc.d/init.d/functions文件中某單詞後面跟一對小括號"()"的行;
grep '\<[[:alpha:]]\+\>()' /etc/rc.d/init.d/functions
或egrep '\<[[:alpha:]]+\>\(\)' /etc/rc.d/init.d/functions ; egrep中\(轉譯符號不需要添加,\<,\>除外,所以egrep中的()就等於grep中的\(\),所以想在egrep中表達(),得轉譯,\+與+同理)
若想切掉後面的},則:egrep '\<[[:alpha:]]+\>\(\)' /etc/rc.d/init.d/functions | cut -d' ' -f1
練習12:使用echo輸出一個路徑,而使用egrep取出其基名;
[root@localhost ~]# echo /etc/passwd/ | egrep -o '\<[[:alpha:]]\>'
[root@localhost ~]# echo /etc/passwd/ | egrep -o '\<[[:alpha:]]+\>/$'
passwd/(紅色/)
[root@localhost ~]# echo /etc/passwd/ | egrep -o '\<[^/]+\>/$' | egrep '\<[^/]+>'
[root@localhost ~]# echo /etc/passwd/ | egrep -o '\<[^/]+\>/$' | egrep '\<[^/]+\>'
passwd/ (白色/)
[root@localhost ~]# echo /etc/passwd/ | egrep -o '\<[^/]+\>/$' | egrep -o '\<[^/]+\>'
passwd
練習13:找出ifconfig命令結果中的1-255之間的數值;
IP的範圍:1.0.0.1 - 223.255.255.254
ifconfig | egrep -o '\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-1][0-9]|22[0-3])\>.\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>.\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>.\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])\>'
解析:1-223.0-255.0-255.0-254去匹配,因爲限定條件爲1-255之間的數值,所以爲1-223.1-255.1-255.1-254去匹配
或:ifconfig | egrep -o --color=auto '\<([1-9]|[1-9][0-9]|1[0-9]{2}|21[0-9]|22[0-3])\>\.(\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>\.){2}\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])\>'
練習14:找出ifconfig命令結果中的IP地址;
ifconfig | egrep -o --color=auto '\<([1-9]|[1-9][0-9]|1[0-9]{2}|21[0-9]|22[0-3])\>\.(\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>\.){2}\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])\>'
解析:因爲IP地址的區間爲1.0.0.1 - 223.255.255.254,所以按照1-223.0-255.0-255.1-254去匹配