正則表達式與grep詳解

寫在前面:

    博客書寫牢記5W1H法則:What,Why,When,Where,Who,How。


本篇主要內容:

● 標準正則表達式

● 擴展正則表達式

擴展與基本正則表達差異

本篇涉及命令:

☉ grep

☉ egrep

☉ fgrep



linux文本處理三劍客:

   grep:

      文本搜索工具。基於“pattern”對給定文本進行搜索操作。

   sed:

      Stream EDitor,流編輯器,行編輯器,本質是一個文本編輯工具。

   awk:

      GNU awk,文本格式化工具;文本報告生成器。


正則表達式:REGular EXpression,REGEX

   由一類特殊字符和文本字符所編寫的模式,其中有些字符不表示其字面意義,而是用來表示控制或通配的同能。

   regular expression可以分爲兩類:

      basic regular expression:BRE

      extended regular expression:ERE

   正則表達式引擎:利用正則表達式模式分析給定文本的程序;

   補充:man 7 regex可以看到正則表達式介紹。


grep系列:

   grep

      支持使用基本正則表達式

   egrep

      支持使用擴展正則表達式

   fgrep

      不支持使用正則表達式,不解析匹配模式字符的含義,按普通字符串對待,速度最快


grep

   print lines matching a pattern

   grep [OPTIONS] PATTERN [FILE...]

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

      -E, --extended-regexp:擴展正則ERE,等同於egrep

      -F, --fixed-strings, --fixed-regexp:關閉正則匹配,等同於fgrep

      -G, --basic-regexp:基礎正則表達BRE,默認項

      -P, --perl-regexp:Perl語言的正則表達支持

      -e PATTERN, --regexp=PATTERN:指定匹配模式(PATTERN),可以多個

      -f FILE, --file=FILE:加載匹配模式文件,文件的每一行一個PATTERN

      -i, --ignore-case:忽略大小寫

      -v, --invert-match:反選,輸出非匹配到的行

      -x, --line-regexp:查找與PATTEN匹配的整行

      -o, --only-matching:只輸出匹配到的字符,而不是整行

      -q, --quiet, --silent:靜默模式,不輸出匹配到的任何內容

      -A NUM, --after-context=NUM:匹配到的行的後NUM行也輸出

      -B NUM, --before-context=NUM:匹配到的行的前NUM行也輸出

      -C NUM, -NUM, --context=NUM:匹配到的行的前後NUM都輸出



基本正則表達式元字符:

   (1)字符匹配:

      .:匹配任意單個字符;

      []:匹配指定範圍的單個字符;

      [^ ]:匹配指定範圍以外的單個字符;

  特殊字符組合常用表:可通過man tr和man grep獲取更多

字符組合含義字符組合含義
alnum所有字母和數字space水平或垂直空白符
digit數字blank水平方向空白符
punct標點符號lower小寫字母
alpha所有字母,即大小寫字母upper大寫字母
graph可輸出字符,不包含空格cntrl控制字符
print可輸出字符,包含空格xdigit十六進制數字,即[0-9a-fA-F]

上表特殊字符組合放入[[::]]內來表示特定含義,如:[[:lower:]]來表示小寫字母。

   實例:

       #匹配單個任意字符
[root@localhost test]# cat file 
Hello
hollo
hallo
[root@localhost test]# grep "h.llo" file 
hollo
hallo
	#匹配a或o單個字符
[root@localhost test]# grep "h[ao]llo" file 
hollo
hallo
	#匹配非a單個字符
[root@localhost test]# grep "[^a]llo" file 
Hello
hollo
	#匹配小寫字母
[root@localhost test]# grep "[[:lower:]].llo" file 
hollo
hallo

   (2)次數匹配:

      用在要指定次數的字符後面,指定字符出現的次數,默認工作在貪婪模式

      貪婪模式:匹配最多字符。如grep "x*y"會匹配xxxxyabc中的xxxxy。

      *:匹配任意次(0次及以上)

      .*:匹配任意長度的任意字符

      \+:匹配一次或多次

      \?:匹配0次或1次

      \{m\}:匹配m次

      \{m,n\}:匹配m-n次

      \{,n\}:匹配0次到n次

      \{m,\}:匹配m次及以上

      注意:由於部分符號可能會有特殊含義,所以需要使用\來轉義。

   實例:

	#測試文件內容如下
[root@localhost test]# cat file 
hllo
hello
heello
hollo
hoollo
hoeollo
	#匹配任意次字母e
[root@localhost test]# grep "he*llo" file
hllo
hello
heello
	#匹配任意長度任意字符
[root@localhost test]# grep "h.*llo" file
hllo
hello
heello
hollo
hoollo
hoeollo
	#匹配一個或多個字母e
[root@localhost test]# grep "he\+llo" file
hello
heello
	#匹配0個或1個字母e
[root@localhost test]# grep "he\?llo" file
hllo
hello
	#匹配2個字母o
[root@localhost test]# grep "ho\{2\}llo" file
hoollo
	#匹配0-2個字母o
[root@localhost test]# grep "ho\{,2\}llo" file
hllo
hollo
hoollo

   (3)位置錨定:

      限制使用匹配模式搜索的文本出現的位置。

      ^:行首錨定,用於PATTEN的最左側。

      $:行尾錨定,用於PATTEN的最右側。

      \<或\b:詞首,用於單詞的左側

      \>或\b:詞尾,用於單詞的右側

         \<PATTEN\>:單詞錨定

      補充:這裏的單詞指的是由非特殊字符組成的連續字符串。

         ^$:表示空行

         ^[[:space:]]$:只有空白字符的行

   實例:

	#測試文件內容
[root@localhost test]# cat file 
 here is a space.
here is not a space
	there is a tab
there is not a tab.
	#匹配t或h開頭的行
[root@localhost test]# grep "^[th]" file 
here is not a space
there is not a tab.
	#匹配“.”結尾的行,注意“.”爲正則表達式特殊含義字符,需要使用“\”轉義
[root@localhost test]# grep "\.$" file
 here is a space.
there is not a tab.
	#匹配單詞“here”
[root@localhost test]# grep "\<here\>" file 
 here is a space.
here is not a space
	#匹配以"here"結尾的單詞
[root@localhost test]# grep "here\>" file 
 here is a space.
here is not a space
	there is a tab
there is not a tab.
	#匹配單詞“here”
[root@localhost test]# grep "\bhere\b" file 
 here is a space.
here is not a space

   (4)分組與引用:

      \(PATTEN\):分組,將PATTEN看做一個整體,可對其整體進行次數匹配等操作。

      \n:後項引用,引用前面分組中的結果。

         分組中匹配到的結果字符會被正則表達式引擎自動記錄與內部變量中,可以使用\1,\2...來引用這些變量。

         注意:正則表達式引擎記錄的內部變量看的是“(”。如:

            pat1\(pat2\)pat3\(pat4\(pat5\)apt6\)

            \1 指的是pat2所匹配的內容;

            \2 指的是pat4\(pat5\)apt6所匹配的內容;

            \3 指的是pat5;

   實例:

	#測試文件內容
[root@localhost test]# cat file 
please say hello with me.HELLO!
please say hello with me.hello!
please say BAY with me.bay!
please say BAY with me.BAY!
OK,good job.
	#匹配“say”後面跟小寫單詞,後面同樣跟這個小寫單詞的行
[root@localhost test]# grep "say \(\<[[:lower:]]*\>\).*\1" file
please say hello with me.hello!
	#匹配“say”後面跟大寫單詞,後面同樣跟這個大寫單詞的行
[root@localhost test]# grep "say \(\<[[:upper:]]*\>\).*\1" file
please say BAY with me.BAY!
	#匹配“say”後面跟一個單詞,後面跟相同單詞的行,不區分大小寫
[root@localhost test]# grep -i "say \(\<[[:upper:]]*\>\).*\1" file
please say hello with me.HELLO!
please say hello with me.hello!
please say BAY with me.bay!
please say BAY with me.BAY!

egrep

   egrep [OPTIONS] PATTERN [FILE...]

   等同於grep -E,參數用法都相同。


擴展正則與基本正則差異:

   (1)擴展正則較基本正則增加了“或”匹配"|"

   (2)擴展正則次數匹配、分組不必添加"/"轉義


擴展正則表達式:

   (1)元字符:

      .:匹配單個任意字符

      []:匹配範圍內單個字符

      [^ ]:匹配範圍外單個字符

   (2)次數匹配:

      *:匹配任意次(0次及以上)

      .*:匹配任意長度的任意字符

      +:匹配一次或多次

      ?:匹配0次或1次

      {m}:匹配m次

      {m,n}:匹配m-n次

      {,n}:匹配0次到n次

      {m,}:匹配m次及以上

   (3)位置錨定:

      限制使用匹配模式搜索的文本出現的位置。

      ^:行首錨定,用於PATTEN的最左側。

      $:行尾錨定,用於PATTEN的最右側。

      \<或\b:詞首,用於單詞的左側

      \>或\b:詞尾,用於單詞的右側

      \<PATTEN\>:單詞錨定

      補充:不同與其他,單詞錨定符號前的"\"不能省略

   (4)分組與引用:

      (PATTEN):分組,將PATTEN看做一個整體,可對其整體進行次數匹配等操作。

      \n:後項引用,引用前面分組中的結果。

   (5)或者:

      |:a|b表示a或者b其中之一,注意結合分組

      如egrep "C|cat" FILE匹配cat或C;

         egrep "(C|c)at" FILE匹配cat或Cat;

   實例:

	#顯示/etc/passwd文件中不以bash結尾的行
[root@localhost test]# egrep -v "bash$"  /etc/passwd
	#找出/etc/passwd文件中的三位或四位數
[root@localhost test]# egrep "\b[0-9]{3,4}\b" /etc/passwd
	#顯示當前系統上root、centos或slackware用戶的相關信息
[root@localhost test]# egrep "^(root|centos|slackware)\>" /etc/passwd
	#echo輸出一個絕對路徑,使用egrep取出其基名
[root@localhost test]# echo "/etc/fstab" | egrep -o "[^/]+/?$"
	#找出ifconfig命令中100-255之間的數
[root@localhost test]# ifconfig | egrep -e "\<1[0-9][0-9]\>" -e "\<2[0-4][0-9]\>" -e "\<25[0-5]\>
	#egrep的“|”用法
[root@localhost test]# egrep "H|hello" file
Hello
hello
H
[root@localhost test]# egrep -o "H|hello" file
H
hello
H
[root@localhost test]# egrep -o "(H|h)ello" file
Hello
hello


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