Linux入門基礎之grep命令詳解及正則表達式

    grep命令是linux下經常使用的命令之一,能根據用戶指定的模式(pattern)對文本進行過濾,顯示出匹配到的。其命令格式爲:

                    grep [OPTIONS] PATTERN [FILE]

例如:我們要查找網卡0中配置的IP地址(該文件路徑: /etc/sysconfig/network-scripts/ifcfg-eth0)---grep 'IPADDR' /etc/sysconfig/network-scripts/ifcfg-eth0

wKiom1RnDl7xp3_jAABjlYv-3pI298.jpg

(注:alias grep='grep --color=auto' 讓匹配結果高亮顯示)   

    grep常用的幾個選項(option)有:

                        -v:反向選取,即顯示 模式過濾之後的剩餘的行

wKiom1RnD4Ljt_VCAAFSWmXCBcY497.jpg

除IPADDR這一行沒有顯示之外,其他內容都顯示給用戶。

                        -i:忽略字符大小寫

wKiom1RnENTws6cxAACp55bQKa0113.jpg

第一條命令沒有過濾到任何內容,因此沒有顯示出結果,忽略大小寫之後,顯示出匹配到的行。

                        -o:僅顯示過濾的內容


wKiom1RnE2yBkiubAAB1_bmXNYU501.jpg

僅顯示根據指定模式過濾的內容。

     那麼什麼是Pattern呢?

     PATTERN表示用戶給定的模式,爲什麼這個地方我們把他叫做模式而不是說成字符,是因爲通常要使用正則表達式(regexp)。而正則表達式就是一類特殊的字符,這類字符當中有些字符通常並不代表其字面意思,而是作爲一種控制或通配(globbing)的功用。這類字符也被稱爲元字符。那麼,讀者朋友們可能就總結出來了,我們所稱的模式Pattern其實由字符加元字符組成的。正則表達式正是由這些元字符所構成,與grep一起過濾文本,並用在以後的shell編程中。

     正則表達式分爲基本正則表達式和擴展正則表達式兩大類。

        基本正則表達式的元字符有以下字符:

        過濾字符的 . 表示匹配任意單個字符。則a..b表示a和b之間有兩個字符。

                   []表示匹配集合內任意單個字符。則a[bc]表示ab或者ac,注:abc也是符合模式的

                   [^]表示匹配集合外任意單個字符。

特殊表達寫法:[0-9]可以用[[:digit:]]表示

              [a-z]可以用[[:lower:]]表示

              [A-Z]可以用[[:upper:]]表示

              [a-zA-Z]即所有字母可以用[[:alpha:]]]表示

              [0-9a-zA-Z]即所有字母和數字可以用[[:alnum:]]表示

              空白(空格字符、Tab製表符等)用[[:space:]]表示

              所有標點符號用[[:punct:]]表示

         匹配次數的(對其緊鄰前面字符出現的次數做出限定) 

                * 表示匹配*前面字符出現任意次0,1,2……,則a*b表示a出現任意次。

                \? 表示匹配?前面字符出現0或1次(\僅代表轉義的作用),則a\?b表示a出現0或1次

                \{m\} 表示匹配{m}前面字符出現m次,則a\{2\}表示a出現2次

                \{m,n\} 表示匹配{m}前面字符最少出現m次最多出現n次,引申出\{m,\}最少m次, \{0,n\} 最多n次。則a\{1,2\}表示a出現最少1次最多2次。

                \+也可以表示爲最少出現1次

         錨定位置的(對字符進行定位,書寫格式簡單記爲:首左,尾右)

                 ^ 表示行首錨定,則^a表示a必須出現在某行的開頭

                 $ 表示行尾錨定,則a$表示某行以a結尾

                 \< 表示詞首錨定,則\<a表示某詞以a開頭 

                 \> 表示詞尾錨定,則\>a表示某詞以a結尾  

        分組符將指定字符分成組,以組的的形式進行匹配。

                \(\),則\(ab\)表示ab爲一組 

                支持後向引用,\1,\2,\3……表示自左向右引用其第#個(開始,第#)結束直接的內容。

        擴展:正則表達式引擎在對某文本內容進行檢索時,若使用了分組符()的模式成功實現了匹配,此次括號內部的Pattern匹配到的文本會被正則表達式引擎予以自動記錄,按照左括號“(”出現的次序,依次記錄在\1,\2,\3……中;匹配到的內容可在同一模式的後面進行引用。

        

    擴展正則表達式用法與基本正則表達式相同,只是書寫格式上不必寫轉義符而已,比基本正則表示多了一條條件選擇符:| 即ab|cd 表示ab或cd

                  i.匹配字符的有    []   [^]

                  ii.匹配次數的有 *      +   {m}    {m,n}     {m,}     {0,n}

                  iii.錨定符有 ^    $    \<或\b    \>或\b

                  iv.分組符有 ()   |

wKiom1RnKHHThrgMAALXQRMNnws533.jpg

wKiom1RnKHaxlRLqAALczhbtQXo698.jpg

正則表達式練習


1、顯示/proc/meminfo文件中以大寫或小寫S開頭的行;

grep -i '^s' /proc/meminfo 

wKiom1RnKhmRTBOOAAFoqnMIgTU123.jpg

2、顯示/etc/passwd文件中其默認shell爲非/sbin/nologin的用戶;

grep -v '/sbin/nologin$' /etc/passwd | cut -d: -f1

wKiom1RnLGPzkZn2AAMPwGABOpA218.jpg

wKioL1RnLNXCyOL4AADSI5TehD4660.jpg

3、顯示/etc/passwd文件中其默認shell爲/bin/bash的用戶;進一步:僅顯示上述結果中其ID號最大的用戶;

 grep '/bin/bash$' /etc/passwd | cut -d: -f1 

wKiom1RnNvXCMYQhAAIKOOJgT44451.jpg

grep '/bin/bash$' /etc/passwd | sort -t: -k3 -n | tail -1 | grep -o  '^[[:alnum:]]\+'

wKioL1RnOR7z39IYAACTsL_zw04111.jpg

4、找出/etc/passwd文件中的一位數或兩位數;

grep '\<[[:digit:]]\{1,2\}\>' /etc/passwd


wKiom1RnOabiDkDpAAQJWwuWPy8691.jpg

5、顯示/boot/grub/grub.conf中以至少一個空白字符開頭的行;

grep '^[[:space:]]\+' /boot/grub/grub.conf

wKioL1RnOqDyfzNmAAFkv761xo8533.jpg

6、顯示/etc/rc.d/rc.sysinit文件中,以#開頭,後面跟至少一個空白字符,而後又有至少一個非空白字符的行;

grep '^#[[:space:]]\+[^[:space:]]\+' /etc/rc.d/rc.sysinit

wKioL1RnOyeBbw8hAAT-XZzDGJ8241.jpg

7、找出netstat -tan命令執行結果中以'LISTEN'(後可有空白字符)結尾的行;

netstat -tan | grep 'LISTEN[[:space:]]*$'


wKiom1RnPAfTTMGZAAFjQgrWnUY207.jpg


8、添加用戶bash, testbash, basher, nologin(SHELL爲/sbin/nologin),而找出當前系統上其用戶名和默認shell相同的用戶;

grep '^\([[:alnum:]]\+\).*\1$' /etc/passwd


wKioL1RnPwXiPKd8AANQQkfNaog193.jpg

wKiom1RnPpSxxdlzAAGZq301dCY689.jpg

9、擴展題:新建一個文本文件,假設有如下內容:

He like his lover.

He love his lover.

He like his liker.

He love his liker.

找出其中最後一個單詞是由此前某單詞加r構成的行。

# nano blog.text

# grep '\(\<[[:alpha:]]\+\>\).*\1r' ./blog.text 


wKiom1RnQWnzPmiwAAD27e2CGno262.jpg

使用egrep完成下面的練習

練習10:顯示當前系統上root、centos或user1用戶的默認shell及用戶名;

egrep '^root|centos|user1\>' /etc/passwdwKioL1RnPwXiPKd8AANQQkfNaog193.jpg

wKioL1RnQ8mx9DtoAAJsxVx30bE798.jpg

練習11:找出/etc/rc.d/init.d/functions文件中某單詞後面跟一對小括號"()"的行;

egrep '\<[[:alpha:]]+\>\(\)' /etc/rc.d/init.d/functions | cut -d' ' -f1

wKioL1RnROri0-UZAAJMqs4unas436.jpg

練習12:使用echo輸出一個路徑,而使用egrep取出其基名;

 echo /tmp/abc-/-s | egrep -o '[^/]+$'

wKioL1RnRgqxii8OAACe5deC5rY796.jpg

練習13:找出ifconfig命令結果中的1-255之間的數值;   

ifconfig | egrep '\<([1-9]|[1-9][0-9]|1[0-9]\+|2[0-4][0-9]|25[0-5])\>'

wKioL1RnR1-hRLtzAAOImfW-Bcw212.jpg

練習14:找出ifconfig命令結果中的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])\>\.\<(1|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>)'

wKiom1RnSqOiAnWfAAEfSkflq9s005.jpg

    經驗之談:把要搜索的文本內容全部看成單個的字符,更容易理解。

    擴展:還有一種快速檢索工具fgrep,但他不支持正則表達式,因此很少使用。

wKiom1RnSvHAtu-YAAKu9MmdRB4986.jpg


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章