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
當字串太多時,可以使用參數 -f 搜尋多個關鍵字,請參考 #grep -f https://benjr.tw/93776 說明.
[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