天天看點

文字檢索秘技之正規表達式grep和egrep

一、總綱(何為正則)

   所謂正則,又稱正規表達式、正規表示法、正常表示法(英語:Regular Expression,在代碼中常簡寫為regex、regexp或RE),計算機科學的一個概念。正規表達式使用單個字元串來描述、比對一系列符合某個句法規則的字元串。在很多文本編輯器裡,正規表達式通常被用來檢索、替換那些符合某個模式的文本。(維基百科如是說)

   為了便于了解,可以将正則想象成為普通語言,普通字元對應的是普通文字,而元字元則對應文法,根據語言的規則,按照文法将文字組合起來,就會表述出你想說的話即想要的文本。

第一式  grep是什麼

   grep(global search regular expression(RE)是一種強大的文本搜尋工具,它能使用正規表達式搜尋文本,并把比對的行列印出來。UNIX的grep家族包括grep、egrep和fgrep。egrep和fgrep的指令隻跟grep有很小不同。egrep是grep的擴充,支援更多的re元字元,fgrep就是fixed grep或fast grep,它們把所有的字母都看做單詞,也就是說,正規表達式中的元字元表示回其自身的字面意義,不再特殊。linux使用GNU版本的grep。它功能更強,可以通過-G、-E、-F指令行選項來使用egrep和fgrep的功能。

格式:

grep [OPTIONS] PATTERN [FILE...]

grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]

第一招:常用選項[OPTIONS]

-v: 反向,顯示不能被模式所比對到的行;

1

2

<code>#檢索檔案/etc/passwd中非#的行</code>

<code>grep</code> <code>-</code><code>v</code> <code>"#"</code> <code>/etc/passwd</code>

<a href="http://s3.51cto.com/wyfs02/M02/12/69/wKiom1MGAhzQprWPAAFbfKAMEW8513.jpg" target="_blank"></a>

<a></a>

-o: 僅顯示被模式比對到的字串,而非整行;

<code>#檢索/etc/passwd檔案中有沒有rpcuser使用者</code>

<code>grep</code> <code>-o </code><code>"rpcuser"</code> <code>/etc/passwd</code>

-i: 不區分字元大小寫, ignore-case

<code>#檢索/etc/fstab中包含u中間跟兩個任意字元,最後一個字元為d的行,不區分大小寫</code>

<code>grep</code> <code>--color -i </code><code>"u..d"</code> <code>/etc/fstab</code>

<a href="http://s3.51cto.com/wyfs02/M02/12/75/wKioL1MII1CCKT1BAAB2w1DiXAM680.jpg" target="_blank"></a>

-E: 支援擴充的正規表達式(加-E可以使用grep啟用egrep的功能 grep -E)

-A #:之後的幾行字元

<a href="http://s3.51cto.com/wyfs02/M01/12/75/wKiom1MIJD6hNdY8AAEysYx-m6E566.jpg" target="_blank"></a>

-B:之前的幾行字元

<a href="http://s3.51cto.com/wyfs02/M01/12/6A/wKiom1MGGYHDxuyPAAD4-1RZy8w076.jpg" target="_blank"></a>

-C #:上下兩行

<a href="http://s3.51cto.com/wyfs02/M02/12/6A/wKioL1MGGciRUgr2AAF6Ms16krQ900.jpg" target="_blank"></a>

-n: 顯示比對行及行号,在顯示出内容的每行前面會顯示行數

第二招:模式(PATTERN)

元字元:不表示字元本身的意義,用于額外功能性的描述

字元比對:

.: 任意單個字元

<code>#在/etc/passwd檔案中檢索包含r後面跟兩個字元,然後是t的行</code>

<code>grep</code> <code>--color </code><code>"r..t"</code> <code>/etc/passwd</code>

<a href="http://s3.51cto.com/wyfs02/M00/12/6B/wKioL1MGHRDjyICxAACwNcdVav0597.jpg" target="_blank"></a>

[ ]: 指定範圍内的任意單個字元

<code>#在/etc/inittab下檢索以S或s後面接任意一個字元,之後是s的行</code>

<code>grep</code> <code>--color </code><code>"[sS].s"</code> <code>/etc/fstab</code>

<code>grep</code> <code>--color </code><code>"jin[[:digit:]]"</code> <code>/etc/passwd</code>

<a href="http://s3.51cto.com/wyfs02/M00/12/76/wKioL1MIJ9KTydTTAAGa6Ta3qlU023.jpg" target="_blank"></a>

[[:alnum:]] 比對任何一個字母或數字([A-Za-z0-9])

[[:alpha:]] 比對任何一個字母([A-Za-z])

[[:lower:]] 比對任何一個小寫字母([a-z])

[[:upper:]] 比對任何一個大寫字母([A-Z])

[[:space:]] 任何一個空白字元:制表符、空格

[[:punct:]] 任何一個标點符号(不包括:[:alnum:]、[:cntrl:]、[:space:]字元集)

[^]:指定範圍外的任意單個字元

<code>#在/etc/selinux/config下檢索非标點符号開始的行</code>

<code>grep</code> <code>--color </code><code>"^[^[:punct:]].*"</code> <code>/etc/selinux/config</code>

<a href="http://s3.51cto.com/wyfs02/M01/12/6A/wKiom1MGJznwh8wNAAB5pARnz1w901.jpg" target="_blank"></a>

位置錨定:用于指定字元出現的位置

^: 錨定行首

<a href="http://s3.51cto.com/wyfs02/M00/12/77/wKiom1MIRB6Qon9bAAB1MrjnWuE728.jpg" target="_blank"></a>

$: 錨定行尾

<code>以</code><code>bash</code><code>結尾的行</code>

<code>grep</code> <code>--color </code><code>"bash$"</code> <code>/etc/passwd</code>

<a href="http://s3.51cto.com/wyfs02/M02/12/6A/wKiom1MGKVuitRs3AAGyWw0D4zo774.jpg" target="_blank"></a>

^$: 空白行

<code>#統計/etc/init/tty.conf檔案中的空行數</code>

<code>grep</code> <code>"^$"</code> <code>/etc/init/tty</code><code>.conf  |</code><code>wc</code> <code>-l</code>

<a href="http://s3.51cto.com/wyfs02/M02/12/6B/wKioL1MGKi2wli5wAAEmJ5b4Lq8079.jpg" target="_blank"></a>

\&lt;char: 錨定詞首,也可以寫成\bchar(注:\b是元字元)

<code>#檢索/etc/passwd 檔案中以r為詞首,後面跟兩個任意字元,最後一個字元是t的行</code>

<code>grep</code> <code>--color </code><code>"\br..t"</code> <code>/etc/passwd</code>

<a href="http://s3.51cto.com/wyfs02/M00/12/6A/wKiom1MGKh2wHelkAACGznXgc6I010.jpg" target="_blank"></a>

char\&gt;: 錨定詞尾,char\b(注:\b也可以用于錨定詞尾)

<code>#以s結尾前面以三個任意字元開頭的系統使用者</code>

<code>grep</code> <code>--color </code><code>"^...s\b"</code> <code>/etc/passwd</code>

<a href="http://s3.51cto.com/wyfs02/M02/12/77/wKioL1MIRjPgz-TWAABy8xAhOQY764.jpg" target="_blank"></a>

次數比對:用來指定比對其前面的字元的次數

*: 任意次(0次或多次)

<code>#a*b重複a為零次或多次(貪婪模式:盡可能的長的去比對字元;)</code>

<code>grep</code> <code>--color ab*bd </code><code>test</code><code>.txt</code>

<a href="http://s3.51cto.com/wyfs02/M02/12/73/wKiom1MHfR-A1c7gAABkxGW9RlU963.jpg" target="_blank"></a>

.*: 比對任意長度的任意字元

<code>#\?: 0次或1次(a\?b 則表示a的比對一次或一次都沒有)</code>

<code>grep</code> <code>--color </code><code>"a\?b"</code> <code>test</code><code>.txt</code>

<a href="http://s3.51cto.com/wyfs02/M02/12/73/wKiom1MHYnjDUxxOAACBPqPITi8355.jpg" target="_blank"></a>

ab*xy:則表示隻能比對*号之前b任意次b(0或多次)

\{m\}: 比對m次

<a href="http://s3.51cto.com/wyfs02/M01/12/73/wKioL1MHYvDD8fUEAAFM_gQVUrg302.jpg" target="_blank"></a>

\{m,n\}:最少比對m次,最多比對n次

<a href="http://s3.51cto.com/wyfs02/M00/12/77/wKioL1MIR-uCBDstAACSatj0rEE334.jpg" target="_blank"></a>

\{m,\}: 至少m次;

\{0,n\}:至多n次;

分組:

\(\)

<code>#檢索檔案中包含w字元之以es為組後面接t然後任意字元,組es重複一次的行</code>

<code>grep</code> <code>--color </code><code>"w\(es\).*\1"</code> <code>test</code><code>.txt</code>

<a href="http://s3.51cto.com/wyfs02/M01/12/73/wKioL1MHYQbwnjWyAACcBcIrk-E509.jpg" target="_blank"></a>

(es)被作為一個組看待,它是一個組,它的名稱是1,然後 .*表示之後的任意個字元,[\1]指代的是前面用括号括起來的es。那麼  egrep 裡的 w(es)t.*\1 就是說 west後面任意字元,再然後再出現es的,這種行被比對到

引用:

\1: 後向引用,引用前面的第一個左括号以及與之對應的右括号中的模式所比對到的内容。(後向引用可以有多次,方法\#(#:數字))

第二式:egrep(grep -E)

為 grep 的擴充版本, 改良了許多傳統 grep 不能或不便的操作. 比方說:

- grep 之下不支援 ? 與 + 這兩種 modifier, 但 egrep 則可.      

注:

?: 比對其前面的字元0或1次;

+: 比對其前面的字元至少1次

|:表示或關系,比如 'gd|good|dog' 表示有gd,good或dog的串

():将部分内容合成一個單元組。比如要搜尋 glad 或 good 可以這樣 'g(la|oo)d',()的好處是可以對小組使用 + ? * 等。

比如要搜尋A和C開頭結尾,中間有至少一個(xyz) 的串,可以這樣 : 'A(xyz)+C'

- grep 不支援 a|b 或 (abc|xyz) 這類"或一"比對, 但 egrep 則可.  

3

4

<code>#輸出包含1或2的行</code>

<code>grep</code> <code>--color </code><code>'\(1\|2\)'</code> <code>/etc/inittab</code>

<code>#或</code>

<code>grep</code> <code>--color -E </code><code>'(1|2)'</code> <code>/etc/inittab</code>

<a href="http://s3.51cto.com/wyfs02/M00/12/74/wKioL1MHciaT6O0iAAEp9pcqeA0598.jpg" target="_blank"></a>

- grep 在處理 {n,m} 時, 需用 \{ 與 \} 處理, 但 egrep 則不需.

諸如此類的... 我個人會建議能用 egrep 就不用 grep 啦..        

第三式:fgrep

不作 RE 處理, 表達式僅作一般字元串處理, 所有 meta 均失去功能.

 ===================================完=========================================

PS:以上是本人學習整理内容,由于能力有限,如有錯漏,歡迎各種磚頭瓦塊.a_c

本文轉自 jinlinger 51CTO部落格,原文連結:http://blog.51cto.com/essun/1361920,如需轉載請自行聯系原作者

繼續閱讀