天天看點

grep和正規表達式的應用

Linux文本處理三劍客

  • grep:文本過濾工具
  • sed:文本編輯器(行),stream editor
  • awk:文本報告生成器,Linux上awk的實作為gawk

grep: Global search REgular expression and Print out theline.

  • 作用:文本搜尋工具,根據使用者指定的“模式(pattern)”逐行去搜尋目标文本,列印比對到的行
  • 模式:由正規表達式的元字元及文本字元所編寫的過濾條件

    文法:grep [OPTIONS] PATTERN [FILE...]:

選項:

  --color=auto:對比對到的串做高亮顯示;

  -v:顯示模式比對不到的行;

  -i:忽略字元大小寫;

  -o:僅顯示能夠被模式比對到的串本行,而且每比對到的一個就分一行,可以友善統計次數;

  -q: 靜默模式;

  -E:使用擴充的正規表達式;

正規表達式分2類:

  • 基本正規表達式:BRE
  • 擴充正規表達式:ERE

基本正規表達式的元字元:(字元不表示其字面意義,而用于表示通配或控制功能)

  • 字元比對:

.:比對任意單個字元;

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

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

[:lower:] 小寫字元

[:upper:] 大寫字元

[:space:] 空格

[:alnum:] 大小寫字元及數字

[:alpha:] 大小寫字元,A-Z,a-z

[:punct:] 标點符号

  • 次數比對:用于要指定其次數的字元的後面,隻能用于前一個字元*:任意次

grep.txt檔案内容

abxy

xay

xxxxxxxy

grep和正規表達式的應用

\?:0或1次

grep和正規表達式的應用

\+:1或多次

\{m\}:精确限制為m次

\{m,n\}:至少m次,至多n次,[m,n]

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

\{m,\}:至少m次

grep和正規表達式的應用

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

grep和正規表達式的應用
  • 位置錨定:

^:行首錨定;用于模式的最左側

$:行尾錨定;用于模式的最右側

\<,\b: 詞首錨定;用于表示單詞的模式的左側

\>,\b:詞尾錨定;用于表示單詞的模式的右側

^$:空白行

  • 分組:\(\)

分組的小括号中的模式比對到的内容,會在執行過程中被正規表達式引擎記錄下來,并儲存内置的變量中;這些變量分别是\1, \2, ...

\1:從左側起,第一個左括号,以及與之配對的右括号中間的模式所比對到的内容;

\2...原理同上,第二個

後向引用:使用變量引用前面的分組括号中的模式所比對到的字元;

擴充的正規表達式元字元及其意義:

    ?  #比對0個或1個在其之前的那個普通字元

    +   #比對1個或多個在其之前的那個普通字元

    ()  #表示一個字元集合或用在expr中

    |   #表示“或”,比對一組可選的字元

練習

    3、顯示/etc/passwd檔案中以bash結尾的行

       grep "\bbash$" /etc/passwd

    4、顯示/etc/passwd檔案中的兩位數或三位數

       grep "\b[0-9]\{2,3\}\b" /etc/passwd

       grep -E "\b[0-9]{2,3}\b" /etc/passwd

    5、顯示`netstat -tan`指令結果中以‘LISTEN’後跟0個、1個或者多個空白字元結尾的行

       netstat -tan | grep "LISTEN[[:space:]]*"

    6、添加使用者bash、testbash、basher以及nologin使用者(nologin使用者的shell為/sbin/nologin); 而後找出/etc/passwd檔案中使用者名與其shell名相同的行

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

    7、顯示目前系統上root、centos或者user1使用者的預設shell和UID (請事先建立這些使用者,若不存在)

       grep -E "centos|user1|root" /etc/passwd | awk -F: '{print $3 "\t" $7}'

    8、找出/etc/rc.d/init.d/functions檔案中某單詞(單詞中間可以存在下劃線)後面跟着一組小括号的行

       grep "\<[0-9a-zA-Z_]\+\>()" /etc/rc.d/init.d/functions

    9、使用echo輸出一個路徑,而後egrep找出其路徑基名;進一步的使用egrep取出其目錄名

       取路徑基名(方法二這種去尾部特定字元的方法很好用哦):

       方法一 echo "/etc/aa/bb/cc/aa5555t.fs/" |grep -Eo "[^/]+/?$" | grep -o ".*[^/]"

       方法二 echo "/etc/aa/bb/cc/aa5555t.fs/" |grep -Eo ".*[^/]" |grep -Eo "[^/]+$" 

       取目錄名(其中有利用貪婪模式原理):

echo "/etc/aa/bb/cc/aa5555t.fs" |grep -Eo "/.*[^/]" |grep -Eo "/.*/" | grep -Eo ".*[^/]" |grep -Eo "[^/]+$"