天天看點

linux文本三劍客之grep及正規表達式詳解

linux文本三劍客之grep及正規表達式詳解

目錄

  • linux文本三劍客之grep及正規表達式詳解
    • 1. grep指令詳解
    • 2. 正規表達式
      • 2.1 基本正規表達式
      • 2.2 擴充正規表達式

1. grep指令詳解

grep指令用于過濾一行中的關鍵字,若比對,則輸出此行内容。

grep指令的文法格式如下:

grep [OPTION]... PATTERN [FILE]...
其中PATTERN為正規表達式,預設支援标準正規表達式
           

grep指令的常用選項如下:

選項 說明
-v 顯示不被比對到的行
-i 忽略字元大小寫
-n 顯示比對的行号
-c 統計比對的次數
-o 僅顯示比對到的字元串
-q 靜默模式,不輸出任何内容
-w 比對整個單詞,而不僅是包含
-e 實作多個選項之間的邏輯或關系
-E 使用擴充的正規表達式
-A # 顯示比對到的行及本行之後#行
-B # 顯示比對到的行及本行之前#行
-C # 顯示比對到的行及本行前後#行
--color=auto 對比對到的字元着色顯示

grep的用法示例如下:

#示例一:grep正常用法
[root@xuzhichao ~]# grep "root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

#執行個體二:顯示行号
[root@xuzhichao ~]# grep -n "root" /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin

#示例三:顯示包含關鍵字的行數
[root@xuzhichao ~]# grep -c "root" /etc/passwd
2

#示例四:邏輯或關系
[root@xuzhichao ~]# grep -e "root" -e "xu" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
xu:x:1000:1000:xu:/home/xu:/bin/bash

#示例五:-w選項比對整個單詞
[root@xuzhichao ~]# echo "xabcy" | grep -w abc
[root@xuzhichao ~]# echo "x abc y" | grep -w abc
x abc y
[root@xuzhichao ~]# echo "x,abc,y" | grep -w abc
x,abc,y

#示例六:-o選項表示隻顯示比對到的内容
[root@xuzhichao ~]# echo "x,abc,y" | grep -o abc
abc
[root@xuzhichao ~]# echo "xabcy" | grep -o abc
abc

#示例七:-A B C 的用法
[root@xuzhichao ~]# grep -n -A3 "root" /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
2-bin:x:1:1:bin:/bin:/sbin/nologin
3-daemon:x:2:2:daemon:/sbin:/sbin/nologin
4-adm:x:3:4:adm:/var/adm:/sbin/nologin
--
10:operator:x:11:0:operator:/root:/sbin/nologin
11-games:x:12:100:games:/usr/games:/sbin/nologin
12-ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
13-nobody:x:99:99:Nobody:/:/sbin/nologin

[root@xuzhichao ~]# grep -n -B3 "root" /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
--
7-shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8-halt:x:7:0:halt:/sbin:/sbin/halt
9-mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10:operator:x:11:0:operator:/root:/sbin/nologin

[root@xuzhichao ~]# grep -n -C3 "root" /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
2-bin:x:1:1:bin:/bin:/sbin/nologin
3-daemon:x:2:2:daemon:/sbin:/sbin/nologin
4-adm:x:3:4:adm:/var/adm:/sbin/nologin
--
7-shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8-halt:x:7:0:halt:/sbin:/sbin/halt
9-mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10:operator:x:11:0:operator:/root:/sbin/nologin
11-games:x:12:100:games:/usr/games:/sbin/nologin
12-ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
13-nobody:x:99:99:Nobody:/:/sbin/nologin

#示例八:-q不輸出内容,可以通過指令傳回結果判斷是否有内容
[root@xuzhichao ~]# grep -q "root" /etc/passwd
[root@xuzhichao ~]# echo $?
0
           

2. 正規表達式

正規表達式用于按照一定模式比對字元串,分為基本正規表達式和擴充正規表達式。

2.1 基本正規表達式

基本真正表達式按照比對的類型,可以分為以下幾種:

  • 字元比對
    元字元 說明
    . 比對任意單個字元,當.放到[]中表示普通的.,不再有特殊意義
    [] 中括号比對指定集合内的任意單個字元,[xu]代表x,u兩個字元中的任意一個
    [0-9] 比對任意數字
    [a-z] 比對任意單個小寫字母
    [:upper:] 比對任意單個大寫字母
    [:lower:] 比對任意單個小寫字母
    [:digit:] 比對任意單個數字
    [:alnum:] 比對任意單個所有字母和數字
    [:alpha:] 比對任意單個大寫和小寫字母
    [:space:] 比對單個空白字元
    [:punctl:] 比對單個标點符号
    [^xu] 比對除了x,u以外的其他單個字元
    [^a-z] 比對除了小寫字母以外的其他單個字元
  • 比對次數
    元字元 說明
    * 比對前面的字元任意次,包括0次
    .* 比對任意長度的任意字元
    ? 比對前面的字元0次或1次
    \+ 比對前面的字元至少一次
    \{n\} 比對前面的字元n次
    \{m,n\} 比對前面的字元至少m次,最多n次
    \{,n\} 比對前面的字元至多n次
    \{n,\} 比對前面的字元至少n次
  • 位置錨定
    元字元 說明
    ^ 行首錨定
    $ 行尾錨定
    ^$ 比對空行
    ^.*$ 比對整行
    ^[[:space:]]*$ 比對空白行
    \< 或 \b詞首 詞首錨定
    \> 或 \b詞尾 詞尾錨定
    注意:單詞中隻能有字母,數字,“-”符号,其餘符号(:,。./)均為單詞的分隔符。
  • 分組
    元字元 說明
    ( \) 将一個多多個字元捆綁到一起,當做一個整體處理。分組括号中的模式所比對到的内容會記錄與正規表達式内部變量中,變量名為\1,\2,\3,...,稱為後項引用。
    \1 表示從左側起第一個左括号以及與之比對的右括号之前的模式所比對的字元
    \2 表示從左側起第二個左括号以及與之比對的右括号之前的模式所比對的字元
    \| 表示“或”
    示例:
    • (string1\+\(string2\)*\),其中\1表示:string1\+\(string2\)*,\2表示string2;
    • a\|b 表示a或b;
    • C\|cat 表示C或cat;
    • \(C\|c\)at表示 Cat或cat;
  • 基本正規表達式的使用示例如下:
    #示例一:取接口ip位址
    [root@xuzhichao ~]# ifconfig eth0 | grep -o "inet [0-9.]\{7,15\}"
    inet 192.168.20.17
    [root@xuzhichao ~]# ifconfig eth0 | grep -o "inet [0-9.]\{7,15\}" | cut -d " " -f 2
    192.168.20.17
    
    #示例二:位置錨定
    [root@xuzhichao ~]# grep "root" /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    operator:x:11:0:operator:/root:/sbin/nologin
    admroot:x:1001:1001::/home/admroot:/bin/bash
    rooter:x:1002:1002::/home/rooter:/bin/bash
    [root@xuzhichao ~]# grep "\<root" /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    operator:x:11:0:operator:/root:/sbin/nologin
    rooter:x:1002:1002::/home/rooter:/bin/bash
    [root@xuzhichao ~]# grep "\<root\>" /etc/passwd   <==相當于-w選項
    root:x:0:0:root:/root:/bin/bash
    operator:x:11:0:operator:/root:/sbin/nologin
    
    #示例三:找出passwd檔案中首尾都是同一個單詞的行
    [root@xuzhichao ~]# grep "^\(.*\):.*\1$" /etc/passwd
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    
    #示例四:判斷centos的主版本号
    [root@xuzhichao ~]# cat /etc/redhat-release 
    CentOS Linux release 7.8.2003 (Core)
    [root@xuzhichao ~]# grep -o " [0-9]\+" /etc/redhat-release 
     7
    [root@xuzhichao ~]# grep -o " [0-9]\+" /etc/redhat-release | grep -o "[0-9]\+"
    7
               

2.2 擴充正規表達式

擴充正規表達式與基本正規表達式差別不多,僅僅是把\符号去掉了。

擴充正規表達式元字元意義如下:

  • 字元比對
    元字元 說明
    . 比對任意單個字元,當.放到[]中表示普通的.,不再有特殊意義
    [] 中括号比對指定集合内的任意單個字元,[xu]代表x,u兩個字元中的任意一個
    [0-9] 比對任意數字
    [a-z] 比對任意單個小寫字母
    [:upper:] 比對任意單個大寫字母
    [:lower:] 比對任意單個小寫字母
    [:digit:] 比對任意單個數字
    [:alnum:] 比對任意單個所有字母和數字
    [:alpha:] 比對任意單個大寫和小寫字母
    [:space:] 比對單個空白字元
    [:punctl:] 比對單個标點符号
    [^xu] 比對除了x,u以外的其他單個字元
    [^a-z] 比對除了小寫字母以外的其他單個字元
  • 比對次數
    元字元 說明
    * 比對前面的字元任意次,包括0次
    .* 比對任意長度的任意字元
    ? 比對前面的字元0次或1次
    + 比對前面的字元至少一次
    {n} 比對前面的字元n次
    {m,n} 比對前面的字元至少m次,最多n次
    {,n} 比對前面的字元至多n次
    {n,} 比對前面的字元至少n次
  • 位置錨定
    元字元 說明
    ^ 行首錨定
    $ 行尾錨定
    ^$ 比對空行
    ^.*$ 比對整行
    [1]*$ 比對空白行
    \< 或 \b詞首 詞首錨定
    \> 或 \b詞尾 詞尾錨定
    注意:單詞中隻能有字母,數字,“-”符号,其餘符号(:,。./)均為單詞的分隔符。
  • 分組
    元字元 說明
    () 将一個多多個字元捆綁到一起,當做一個整體處理。分組括号中的模式所比對到的内容會記錄與正規表達式内部變量中,變量名為\1,\2,\3,...,稱為後項引用。
    \1 表示從左側起第一個左括号以及與之比對的右括号之前的模式所比對的字元
    \2 表示從左側起第二個左括号以及與之比對的右括号之前的模式所比對的字元
    | 表示“或”
  • 擴充正規表達式的使用示例如下:
    #示例一:檢視/proc/meminfo下以大小寫s開頭的行
    [root@xuzhichao ~]# grep -E "^(s|S).*" /proc/meminfo 
    [root@xuzhichao ~]# grep -e "^s.*" -e "^S.*" /proc/meminfo
    
    #示例二:顯示/etc/passwd中的兩位或三位數字
    [root@xuzhichao ~]# grep -E "\<[0-9]{2,3}\>" /etc/passwd
    
    #示例三:顯示/etc/passwd檔案中不以/bin/bash結尾的行
    [root@xuzhichao ~]# grep -v ".*/bin/bash$" /etc/passwd
    
    #示例四:查找/etc/grub2.cfg檔案中,至少以一個空白字元開頭且後面有非空白字元的行
    [root@xuzhichao ~]# grep -E "^[[:space:]]+[^[:space:]]+" /etc/grub2.cfg
    
    #示例五:取磁盤使用率,從大到小排序
    [root@xuzhichao ~]# df | grep "/dev/" | grep -Eo "[0-9]{1,3}%" | tr -d "%" | sort -rn
    
    #示例六:查找/etc/rc.d/init.d/functions檔案中所有函數名,即以一個單詞(包括_)開頭,後面跟一個小括号的行
    [root@xuzhichao ~]# grep -E "^[[:alnum:]_]*\(\)" /etc/rc.d/init.d/functions
    
    #示例七:取/etc/rc.d/init.d/functions/的目錄名
    [root@xuzhichao ~]# echo "/etc/rc.d/init.d/functions/" | grep -Eo "^.*/." | grep -Eo "^.*/"
    /etc/rc.d/init.d/
    
    #示例八:取/etc/rc.d/init.d/functions/的檔案名
    [root@xuzhichao ~]# echo "/etc/rc.d/init.d/functions/" | grep -Eo "[^/]*/?$" 
    functions/
    
    #示例九:精确比對IP位址格式
    #IP位址一般包括0-9,10-99,100-199,200-249,250-255
    #0-255的正規表達式表示方法為([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])
    [root@xuzhichao ~]# ifconfig eth0 | grep -Eo "([0-9]\.|[1-9][0-9]\.|1[0-9][0-9]\.|2[0-4][0-9]\.|25[0-5]\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"
    192.168.20.17
    255.255.255.0
    192.168.20.255
    
    #示例十:正規表達式比對手機号
    [root@xuzhichao ~]# grep -Eo "\<1[3-9][0-9]{9}\>"
    
    #示例十一:正規表達式比對郵箱
    #郵箱@字首的幾種類型:
    #1、純數字         [email protected] 
    #2、純字母      [email protected]
    #3、字母數字混合   [email protected]
    #4、帶點的      [email protected]
    #5、帶下劃線     [email protected]
    #6、帶連接配接線     [email protected]
    #郵箱@字尾的類型:
    #1、[email protected]
    #2、[email protected]
    #*至少有兩處單詞
    #*頂級域名一般為2~4位(如cn、com、club)
    #預設字首、字尾不以\'_\'、\'-\'、\'.\'結尾,是以正則可以寫成:
    [root@xuzhichao ~]# grep -E "^[[:alnum:]]+([-_.][[:alnum:]]+)*@([[:alnum:]]+[.-])+[[:alnum:]]{2,4}$"
               
  1. [:space:] ↩︎