首頁 > 軟體

Linux正規表示式grep與egrep

2020-06-16 18:02:14

正規表示式:它是指一個用來描述或者匹配一系列符合某個句法規則的字串的單個字串。在很多文字編輯器或其他工具裡,正規表示式通常被用來檢索或替換那些符合某個模式的文字內容。
其實正規表示式,只是一種思想,一種表示方法。只要我們使用的工具支援表示這種思想那麼這個工具就可以處理正規表示式的字串。常用的工具有grep, sed, awk,這三個都是針對文字的行才操作的。

grep  過濾器
語法: grep  [-cinvABC]  'word'  filename

-n    顯示行號
-c    count統計符合要求的行數
-v    取反,不包含所選字元的
-i    不區分大小寫
-r    會把目錄下面所有的檔案遍歷  例如: grep -r 'root' ./
-A    後面跟數位,A2表示列印符合要求的行及下面二行
-B    後面跟數位,B2表示列印符合要求的行及上面二行
-C    後面跟數位,C2表示列印符合要求的行及上下各二行
^    行首,開頭
$    行尾,結尾
空行用 ^$ 表示

可以做一個別名alias grep="grep --color" 寫入到.bashrc裡面;以後輸入grep命令時查詢的關鍵字元會顏色顯示,方便區分。

過濾帶有某個關鍵詞的行並輸出行號,顏色顯示關鍵詞
[root@localhost ~]# grep -n --color 'root' passwd 
1:root:x:0:0:root:/root:/bin/bash
11:operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ~]# grep -o --color 'root' passwd | wc -l
4

加-o 統計包含關鍵詞的個數;

過濾不帶有某個關鍵詞的行,並輸出行號;
[root@ linuxidc.com ~]# grep -nv 'nologin' /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
6:sync:x:5:0:sync:/sbin:/bin/sync
7:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8:halt:x:7:0:halt:/sbin:/sbin/halt
20:user1:x:600:501::/home/user1:/bin/bash
23:MySQL:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash

過濾以nologin結尾的,系統禁止登陸的所有使用者;
[root@localhost ~]# grep 'nologin$' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

範例,列印關鍵字halt所在行的A2 B2 C2
[root@ linuxidc.com ~]# grep -A2 'halt' passwd 
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
[root@ linuxidc.com ~]# grep -B2 'halt' 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
[root@ linuxidc.com ~]# grep -C2 'halt' 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
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin

把所有以#號開頭的行去除

[root@ linuxidc.com ~]# grep -v '^#' /etc/inittab 
id:3:initdefault:

去除所有空行和以#號開頭的行

[root@ linuxidc.com ~]# grep -v '^#' /etc/crontab |grep -v '^$'
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

範例說明,列印數位或字母開頭,及不是字母和數位開頭的;
[root@ linuxidc.com tmp]# cat test.txt 
helloworld
abc
abc11111
#differt
12345
67899
123def

[0-9]代表任意一個數位,整個命令意思篩選出包含任意一個數位的行;

[root@ linuxidc.com tmp]# grep '[0-9]' test.txt 
abc11111
12345
67899
123def

[^0-9]代表除0-9之外的任意一個字元,整個命令的意思是篩選出不包含數位的行;

[root@ linuxidc.com tmp]# grep '[^0-9]' test.txt 
helloworld
abc
abc11111
#differt
123def

^[^0-9]代表不是數位開頭的;

[root@ linuxidc.com tmp]# grep '^[^0-9]' test.txt 
helloworld
abc
abc11111
#differt

[a-z]代表任意一個英文字母;

[root@ linuxidc.com tmp]# grep '[a-z]' test.txt 
helloworld
abc
abc11111
#differt
123def

[^a-z]代表除英文字母以外的;

[root@ linuxidc.com tmp]# grep '[^a-z]' test.txt 
abc11111
#differt
12345
67899
123def

^[^a-z]代表不是英文字母開頭的文字;

[root@ linuxidc.com tmp]# grep '^[^a-z]' test.txt 
#differt
12345
67899
123def

[ ] 如果是數位的話就用[0-9]這樣的形式,當然有時候也可以用這樣的形式[15]即只含有1或者5,注意,它不會認為是15。如果要過濾出數位以及大小寫字母則要這樣寫[0-9a-zA-Z]。另外[ ]還有一種形式,就是[^字元] 表示除[ ]內的字元之外的字元。

過濾任意一個字元與重複字元
[root@ linuxidc.com ~]# grep 'h..t' /etc/passwd
halt:x:7:0:halt:/sbin:/sbin/halt

'.'點表示任意的一個字元,上面例子為把符合h與t之間有2個任意字元的行過濾出來。

'*'代表零個或多個任意的字元
'ooo*'代表oo,ooo,oooo 或者更多的o
[root@ linuxidc.com ~]# grep 'ooo*' /etc/passwd
root:x:0:0:root:/root:/bin/bash
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin

'.*'表示零個或多個任意字元,等於所有的,空行也包含在內。
[root@ linuxidc.com ~]# grep '.*' /etc/passwd |wc -l
24
[root@ linuxidc.com ~]# wc -l /etc/passwd
24 /etc/passwd

指定要過濾字元出現的次數
{ }內部為數位,表示前面字元要重複的次數。表示兩個O即包含OO的行。{ }左右都需要加脫意字元
grep -E 代表增強版的grep即egrep,使用egrep不需要脫意;
123456789 [root@ linuxidc.com ~]# grep 'o{2}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
[root@localhost ~]# grep -E 'o{2}' passwd 
[root@localhost ~]# egrep 'o{2}' passwd

[root@ linuxidc.com ~]# cat test.txt 
root:hot
abcde
spoool
spool
spol
spl

範例,過濾字母o出現1到3次的行

[root@ linuxidc.com ~]# grep 'o{1,3}' test.txt 
root:hot
spoool
spool
spol

{ } 還可以表示一個範圍,格式為{n1,n2} n1<n2 表示重複n1到n2次前面的字元,n2還可以為空,則表示大於等於n1次。

egrep為grep的擴充套件版本,我們可以用egrep完成grep不能完成的工作,當然了grep能完成的egrep完全可以完成。
grep -E = egrep

1、篩選一個或一個以上前面的字元    字元後面使用+
[root@ linuxidc.com ~]# cat test.txt 
rot:x:0:0:rot:/rot:/bin/bash
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
rooooot:x:0:0/roooooot:/bin/bash
11111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
[root@ linuxidc.com ~]# egrep 'o+' test.txt 
rot:x:0:0:rot:/rot:/bin/bash
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
rooooot:x:0:0/roooooot:/bin/bash
[root@ linuxidc.com ~]# egrep 'oo+' test.txt 
root:x:0:0:root:/root:/bin/bash
rooooot:x:0:0/roooooot:/bin/bash
[root@ linuxidc.com ~]# egrep 'ooo+' test.txt 
rooooot:x:0:0/roooooot:/bin/bash

2、篩選零個或一個前面的字元    字元後面使用?

[root@ linuxidc.com ~]# egrep 'o?' test.txt 
rot:x:0:0:rot:/rot:/bin/bash
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
rooooot:x:0:0/roooooot:/bin/bash
11111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
[root@ linuxidc.com ~]# egrep 'oo?' test.txt 
rot:x:0:0:rot:/rot:/bin/bash
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
rooooot:x:0:0/roooooot:/bin/bash
[root@ linuxidc.com ~]# egrep 'ooo?' test.txt 
root:x:0:0:root:/root:/bin/bash
rooooot:x:0:0/roooooot:/bin/bash
[root@ linuxidc.com ~]# egrep 'oooo?' test.txt 
rooooot:x:0:0/roooooot:/bin/bash

3、篩選字串1或字串2    包含裡面任意一個字串的列印出來

[root@ linuxidc.com ~]# egrep 'aaa|111|ooo' test.txt 
rooooot:x:0:0/roooooot:/bin/bash
11111111111111111111111111111111
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

4、egrep中()的應用

[root@ linuxidc.com ~]# egrep 'r(oo)|(mo)n' test.txt 
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
rooooot:x:0:0/roooooot:/bin/bash

用( )表示一個整體,例如(oo)+ 表示1個'oo'或者多個'oo'

[root@ linuxidc.com ~]# egrep '(oo)+' test.txt 
root:x:0:0:root:/root:/bin/bash
rooooot:x:0:0/roooooot:/bin/bash

5、egrep中[ ]的應用   

方括號內的字元為其中的一個;[^o]為除了字母o之外的;
範例:r開頭t結尾的;;
[root@localhost ~]# egrep 'r[o]t' test.txt 
rot:x:0:0:rot:/rot:/bin/bash

r開頭後面有o的

[root@localhost ~]# egrep 'r[o]' test.txt 
rot:x:0:0:rot:/rot:/bin/bash
root:x:0:0:root:/root:/bin/bash
rooooot:x:0:0/roooooot:/bin/bash

r開頭後面不是o的;

[root@localhost ~]# egrep 'r[^o]' test.txt 
rrt
rtx

t為結尾的前面字元不是o的;

[root@localhost ~]# egrep '[^o]t' test.txt 
rrt
rtx

. * + ? 符號的總結
.    表示任意一個字元(包括特殊字元 空格 # $ ?)
*    表示零個或多個*前面的字元
.*  表示任意個任意字元(包含空行)
+    表示1個或多個+前面的字元
?    表示0個或1個?前面的字元
其中,+ ? grep不支援,egrep才支援。

"ro.*t" 表示以ro開頭一直到t結尾的
[root@localhost ~]# grep 'ro.*t' test.txt 
rot:x:0:0:rot:/rot:/bin/bash
root:x:0:0:root:/root:/bin/bash
rooooot:x:0:0/roooooot:/bin/bash

圖片顯示的更詳細,方便大家理解。

grep如果需要篩選字串 | 管道需要加脫意才可以使用;

grep使用簡明及正規表示式  http://www.linuxidc.com/Linux/2013-08/88534.htm

Linux下Shell程式設計——grep命令的基本運用 http://www.linuxidc.com/Linux/2013-06/85525.htm

grep 命令詳解及相關事例 http://www.linuxidc.com/Linux/2014-07/104041.htm

Linux基礎命令之grep詳解 http://www.linuxidc.com/Linux/2013-07/87919.htm

設定grep高亮顯示匹配項 http://www.linuxidc.com/Linux/2014-09/106871.htm

Linux grep命令學習與總結 http://www.linuxidc.com/Linux/2014-10/108112.htm

本文永久更新連結地址http://www.linuxidc.com/Linux/2015-04/116332.htm


IT145.com E-mail:sddin#qq.com