417 瀏覽數

grep 正規表示式

grep 是在 Linux 蠻常用的指令,主要是在一群文字資料裡搜尋 Keyword 關鍵字在哪一行.

#grep -E , #grep -e

  • -e PATTERN, –regexp=PATTERN
  • -E, –extended-regexp

兩者的差別是 -E 支援 extended regular expression ,grep 支援三種不同的正規表示式 “basic” (BRE), “extended” (ERE) 及 “perl” (PCRE).
Basic 與 Extended Regular Expressions 差別
在 basic 正規表示式 meta-characters ?, +, {, |, (, and ) 需要加入 backslashed 來使用 \?, \+, \{, \|, \(, and \) ,其他如 / 也可用 \/ 來表示.

這些 PATTERN 要如何使用,必須依據 Linux 下的正規表示式.

‘PATTERN’

‘ ‘ 可以用來搜尋特定字串.有時會看到 單引號 ‘PATTERN’ 或是 雙引號 “PATTERN” 都是可以使用的.

root@ubuntu:~# grep -e 'root' /etc/passwd
root:x:0:0:root:/root:/bin/bash
root@ubuntu:~# grep -e "root" /etc/passwd
root:x:0:0:root:/root:/bin/bash

一般使用時不加上 ‘ ‘ , ” ” 也是可以使用的.

root@ubuntu:~# grep -e root /etc/passwd
root:x:0:0:root:/root:/bin/bash

也可以同時指定多個檔名,搜尋結果會在行的最前面顯示檔案名稱.

root@ubuntu:~# grep -e root /etc/passwd /etc/group
/etc/passwd:root:x:0:0:root:/root:/bin/bash
/etc/group:root:x:0:

* 代表目前路徑下的所有檔案都進行搜尋.

root@ubuntu:~# grep -e root *
b.txt:Linux Foundation 1.1 root hub 
b.txt:Linux Foundation 2.0 root hub 

可以使用 . 來代表任意字元.

root@ubuntu:~# grep -e "ba.." /etc/passwd
root:x:0:0:root:/root:/bin/bash
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
ben:x:1000:1000:Ben,,,:/home/ben:/bin/bash

可以使用 * 來代表零個或多個先前字元.

root@ubuntu:~# grep -e "ww*" /etc/passwd
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
whoopsie:x:109:116::/nonexistent:/bin/false

可以使用 .* 來代表任意字元.

root@ubuntu:~# grep -e "ww.*" /etc/passwd
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

‘( PATTERN1 | PATTERN 2 )’

如果要搜尋的字串有多種可能(有可能已經忘記正確字串的名字),這時候就可以使用 #egrep ,等同 #grep -E (Extended Regular Expressions ) ,直接來看下面的例子.他會找出 root 或是 www 開頭的字串.

root@ubuntu:~# grep -e '(root|www)' /etc/passwd
root@ubuntu:~# grep -E '(root|www)' /etc/passwd
root:x:0:0:root:/root:/bin/bash
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

[Char] , [^Char]

剛剛是依據字串,可以利用中括號 [] 來搜尋特定字元.而 [^Char] 是找出不含該字元的行.

找 bin 或是 ben .

root@ubuntu:~# grep -e b[ie]n /etc/group
bin:x:2:
adm:x:4:syslog,ben
cdrom:x:24:ben
sudo:x:27:ben
dip:x:30:ben
plugdev:x:46:ben
lpadmin:x:113:ben
ben:x:1000:
sambashare:x:128:ben

搜尋出 除了 ben 以外的 b.n (. 來代表任意字元).

root@ubuntu:~# grep -e b[^e]n /etc/group
bin:x:2:

正規表示式字元可以使用下面的的特殊符號來表示:

  • [:alnum:] # 文字或是數位字元,表示為 [A-Z,a-z,0-9]
  • [:alpha:] # 文字字元,表示為 [A-Z,a-z]
  • [:lower:] # 小寫字元,表示為 [A-Z]
  • [:upper:] # 大寫字元,表示為 [a-z]
  • [:digit:] # 數位字元,表示為 [0-9]
  • [:xdigit:] # 十六進位數字 0-9,A(10),B(11),C(12),D(13),E(14),F(15),表示為 [0-9,a-f,A-F]
  • [:space:] # 所有空白字元 ,含 空白鍵, Tab, CR (新行)
  • [:graph:] # 除了空字元 (空白鍵與 Tab 按鍵) 外的其他鍵.
  • [:print:] # 非空字元 ,包括空格.
  • [:cntrl:] # 控制字元.
  • [:punct:] # 標點符號.

找出指令 # ifconfig ens33 裡面有關於數字的部分.

root@ubuntu:~# ifconfig ens33 | grep -e "[[:digit:]]"
ens33     Link encap:Ethernet  HWaddr 00:0c:29:3c:1c:8a  
          inet addr:172.16.15.130  Bcast:172.16.15.255  Mask:255.255.255.0
          inet6 addr: fe80::9500:4488:f396:fea3/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:9220 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5248 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:7776788 (7.7 MB)  TX bytes:523434 (523.4 KB)

^ , $

如果要找的資料一定在字行首時, 請使用 “^” (指匹配的字符串在行首)

root@ubuntu:~# grep -e "^ben" /etc/passwd
ben:x:1000:1000:Ben,,,:/home/ben:/bin/bash

如果要找的資料一定在字行尾時, 請使用 “$” (指匹配的字符串在行尾)

root@ubuntu:~# grep -e "bash$" /etc/passwd
root:x:0:0:root:/root:/bin/bash
ben:x:1000:1000:Ben,,,:/home/ben:/bin/bash

這些正規表示式,都可以組合使用.

下面的例子使用 #egrep (等同 #grep -E) ,他會找出 nofork 或是 nogroup 開頭的字串.

root@ubuntu:~# grep -E '^no(fork|group)' /etc/group
nogroup:x:65534:

grep 也是可以直接用不用參數,不過要搜尋的字尾要加入 \

root@ubuntu:~# grep '^no\(fork\|group\)' /etc/group
nogroup:x:65534:

\{\}

x\{m\} 在字串裡面字元 x 重覆 m次 .’0\{5\}’ 表示整個字串裡面 0 這個字元重覆了 5 次.
x\{m,\} 在字串裡面字元 x 重覆 m次 .’0\{5\}’ 表示整個字串裡面 0 這個字元重覆了至少 5 次(以上的也算).
x\{m,n\} 在字串裡面字元 x 重覆 m次 .’0\{1,5\}’ 表示整個字串裡面 0 這個字元重覆了 1(最少)到 5(最多)次.
[a-z]\{m,n\} 在字串裡面字元 a-z 重覆 m次 .’a-z\{1,5\}’ 表示整個字串裡面 0 這個字元重覆了 1(最少)到 5(最多)次.

下面範例用來搜尋出 指令 #ifconfig 裡面提供的 IP , Bcast 及 Mask 相關資訊.

root@ubuntu:~# ifconfig ens33 | grep -e "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
          inet addr:172.16.15.130  Bcast:172.16.15.255  Mask:255.255.255.0

ens33 是我的網卡名稱,請依據實際狀況做修改.
[0-9]\{1,3\}\ 所代表的是,字元可以是 0-9 任一,可以重覆 1(最少)到 3(最多)次.

還可以利用前面正規表示式的特殊符號,上個例子可以改寫成如下.

root@ubuntu:~# ifconfig ens33 | grep -e "[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}"
          inet addr:172.16.15.130  Bcast:172.16.15.255  Mask:255.255.255.0

發表迴響