grep、egrep、fgrep以及正則表達式學習總結

一、grep起源

二、grep用處

三、grep使用

    PATTERN是一個普通字符串

    PATTERN是一個正則表達式

    基本正則表達式

    擴展正則表達式



PS:爲了能更好的學習每一個知識,我在每一個知識點後面都有加一個例子,自己多多動手,多多練習,這樣效果纔會更好。

一、grep起

  grep原先是ed下的一個應用程序,其名稱來自於g/re/p(globally search a regular expression and print,以正規表示法進行全域查找以及打印),在ed下,輸入g/re/p這個命令後,會將所有符合原先定義的字符串,以行爲單位打印出來

 

二、grep用處

  grep是用來搜索文本或者搜索某些文件裏面的行,這些行裏面包括和給定的字符串或者單詞相匹配的字符串或者單詞。默認情況下,grep顯示出匹配到的行。用grep搜索文本,找到裏面匹配一個或者多個正則表達式的行,並且輸出這些行。Grep被認爲是UNIX和其他類UNIX操作系統中最有用的命令之一。

 

三、grep使用

  • grep [OPTIONS] PATTERN[FILE...]

  • grep[OPTIONS] PATTERN [FILE...] 中的PATTERN可以是一個字符長,也可以是一個正則表達式

 

PATTERN是一個字符串

grep常用選項:

--color

  •  搜索到"hi"字符串,顯示爲紅色,auto表示自動的

  • ps:建議把grep用alias別名一下,這樣的話,以後用grep搜索到的內容不用加color參數就會高亮顯示,方法:alias grep='grep --color=auto'

  • 注意:後文的代碼我在執行的時候是高亮顯示的,但是由於這個博客編輯器的原因,沒有辦法高亮顯示了,建議大家把代碼自己執行一下,自己去分析結果,這樣學習效果纔會有。

[root@localhost bash]# grep --color=auto 'hi' b.txt
hi jerry

-v:反向選取,以下面爲例,就是不包含"hi"字符串

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.

[root@localhost bash]# grep -v 'hi' b.txt
hello world
my name is linux.

-o:僅顯示匹配到的內容

[root@localhost bash]# grep 'hi' b.txt
hi jerry
[root@localhost bash]# grep -o 'hi' b.txt
hi

-n:在查出來的每個行的前面加上每行在文件中的行號

[root@localhost bash]# cat -n /etc/issue
     1    CentOS release 6.5 (Final)
     2    Kernel \r on an \m
     3    
     4    Mage Education Learning Services
     5    http://www.magedu.com
     6    
[root@localhost bash]# grep -n 'www' /etc/issue
5:http://www.magedu.com

-i:忽略字符大小寫,以下面爲例,加上-i之後,能匹配到"My"了

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
My name is linux.

[root@localhost bash]# grep 'my' b.txt
my name is linux.
[root@localhost bash]# grep -i 'my' b.txt
my name is linux.
My name is linux.

 

-A #:把匹配到的行的後#行也打印出來,以下面爲例,把匹配到的那一行的後兩行也打印出來;

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?

[root@localhost bash]# grep -A 2 'what' b.txt
what is your name?
Learn linux is fun.
Do you think so?

-B #:把匹配到的行的前#行業打印出來,以下面爲例,把匹配到的那一行的前兩行也打印出來;

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?

[root@localhost bash]# grep -B 2 'what' b.txt
my name is linux.
Hello world
what is your name?

-C #:把匹配到的行的前#行和後#行也打印出來,如下所示,把匹配到那行的前後兩行都打印出來;

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?

[root@localhost bash]# grep -C 2 'what' b.txt
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?

 

3.2PATTERN是一個正則表達式:

 儘管直接使用最簡單直接的pattern字串可以完成一些重要的任務,但是grep命令的真正的威力在於它可以使用正則表達式來完成複雜的模式字串的匹配。

3.2.1 什麼是正則表達式?

正則表達式:

正則表達式又稱正規表達式、正規表示法、正規表示式、規則表達式、常規表達式(英文:Regular Expression—>這裏正好和grep的英文名對應,grep就是搜索正規表達式並且打印輸出),在代碼中常常簡寫爲regex,regexp或RE,計算機科學的一個概念。正則表達式使用單個字符串來描述、匹配一系列符合某個句法規則的字符串。在很多文本編輯器裏,正則表達式通常被用來檢索、替換那些符合某個模式的文本。許多程序設計語言都支持利用正則表達式進行字符串操作。例如,在Perl中就內建了一個功能強大的正則表達式引擎。正則表達式這個概念最初是由UNIX中的工具軟件(例如sed和grep)普及開的。正則表達式通常縮寫成”regex”,單數有regexp、regex,複數有regexps、regexes、regexen。

正則表達式歷史:

最初的正則表達式出現於理論計算機科學的自動控制理論和形式化語言理論中。在這些領域中有對計算(自動控制)的模型和對形式化語言描述與分類的研究。 1940年,WarrenMcCulloch與Walter Pitts將神經系統中的神經元描述成小而簡單的自動控制元。 1950年代,數學家斯蒂芬·科爾·克萊尼利用稱之爲“正則集合”的數學符號來描述此模型。肯·湯普遜將此符號系統引入編輯器QED,然後是Unix上的編輯器ed,並最終引入grep自此,正則表達式被廣泛地使用於各種Unix或者類似Unix的工具,例如Perl。

正則表達式兩類

grepPATTERN中分兩類正則表達式:

  •   基本正則表達式:

  •   擴展正則表達式

 

Grep命令中使用的是基本的正則表達式,如果想使用更高級也就是擴展正則表達式需要指定選項-E,相當於egrep命令。

基本正則表達式:
包括四種類型的模式匹配規則
字符匹配:
  •  .:點號是用來匹配任意單個字符
  • 如下所示:"t...k"是匹配"t"和"k"之間有3個字符的字符串

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?

[root@localhost bash]# grep 't...k' b.txt
Do you think so?
  • []:匹配指定集合中的任意單個字符,注意是單個字符

  • [[:digit:]] 或者 [0-9] -->匹配0到9之間的單個數字

  • 如下:查找b.txt中含有數字的行

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?
10 you think so?
[root@localhost bash]# grep '[[:digit:]]' b.txt
10 you think so?


[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?
10 you think so?
[root@localhost bash]# grep '[0-9]' b.txt
10 you think so?

 

  • [[:lower:]]  [a-z]  -->匹配單個小寫字母

  • 如下:查找b_test.txt中含有小寫字母的行

[root@localhost bash]# cat b_test.txt
HI ,WHAT IS YOUR NAME?
MY NAME IS JERRY
HOW OLD ARE YOU?
I am 22.
[root@localhost bash]# grep '[[:lower:]]' b_test.txt
I am 22.

[root@localhost bash]# cat b_test.txt
HI ,WHAT IS YOUR NAME?
MY NAME IS JERRY
HOW OLD ARE YOU?
I am 22.
[root@localhost bash]# grep '[a-z]' b_test.txt

 

  • [[:upper:]] [A-Z]  -->匹配單個大寫字母

  • 如下:查找b.txt中含有大寫字母的行

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?
10 you think so?
[root@localhost bash]# grep '[[:upper:]]' b.txt
Hello world
Learn linux is fun.
Do you think so?

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?
10 you think so?
[root@localhost bash]# grep '[A-Z]' b.txt
Hello world
Learn linux is fun.
Do you think so?

 

  • [[:alpha:]] [a-zA-Z] -->匹配單個大寫字母或者單個小寫字母

  • 如下:查找b.txt中不含大小寫字母的行

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?
10 you think so?
100
[root@localhost bash]# grep -v '[[:alpha:]]' b.txt
100

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?
10 you think so?
100
[root@localhost bash]# grep -v '[a-zA-Z]' b.txt
100

 

  • [[:alnum:]] [0-9a-zA-Z] -->匹配單個0到9之間的數字或者單個小寫字母或者單個大寫字母

  • 如下:查找含有數字或者小寫字母或者大寫字母的行;

[root@localhost bash]# cat c.txt
how old are you ?
i am 22
*****
[root@localhost bash]# grep '[[:alnum:]]' c.txt
how old are you ?
i am 22

[root@localhost bash]# cat c.txt
how old are you ?
i am 22
*****
[root@localhost bash]# grep '[0-9a-zA-Z]' c.txt
how old are you ?
i am 22

 

  • [[:space:]] -->匹配空白字符包括空格、tab

  •  如下:查找含有空格的行

[root@localhost bash]# cat c.txt
how old are you ?
i am 22
*****
youyouyouyou

[root@localhost bash]# grep '[[:space:]]' c.txt
how old are you ?
i am 22

 

  • [[:punct:]]-->匹配單個除了數字、大小寫字母的符號

  • 如下:查找含有除了數字、大小寫字母的行

[root@localhost bash]# cat c.txt
how old are you ?
i am 22
*****
youyouyouyou
my name is jerry,and what is your name?

[root@localhost bash]# grep '[[:punct:]]' c.txt
how old are you ?
*****
my name is jerry,and what is your name?

 

  • [^]:匹配指定集合外的任意單個字符

  • 如下:查找含有非數字的行

[root@localhost bash]# grep '[^0-9]' b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?
10 you think so?
[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
what is your name?
Learn linux is fun.
Do you think so?
10 you think so?
100


 

  匹配次數:
  • 對其前面緊鄰字符所能出現的次數做出限定

  • *:匹配其前面的字符任意次,0次1次多次都行;

  • 如下:可以自行理解下面的過程

[root@localhost bash]# cat d.txt
xy
xxy
xxxy
xxxxy
y
nxy
[root@localhost bash]# grep 'x*y' d.txt
xy
xxy
xxxy
xxxxy
y
nxy
[root@localhost bash]# grep 'xx*y' d.txt
xy
xxy
xxxy
xxxxy
nxy
[root@localhost bash]# grep 'xxx*y' d.txt
xxy
xxxy
xxxxy


  • \?: 匹配其前面的字符0次或者1次,也就是說沒有可以,有的話只能出現一次;

  • 如下:可以自行理解下面的過程

[root@localhost bash]# cat d.txt
xy
xxy
xxxy
xxxxy
y
nxy
[root@localhost bash]# grep 'x\?y' d.txt
xy
xxy
xxxy
xxxxy
y
nxy
[root@localhost bash]# grep 'xx\?y' d.txt
xy
xxy
xxxy
xxxxy
nxy


  • \+: 匹配其前面的字符至少一次;

  •  如下:可以自行理解下面的過程

[root@localhost bash]# cat d.txt
xy
xxy
xxxy
xxxxy
y
nxy
[root@localhost bash]# grep 'x\+y' d.txt
xy
xxy
xxxy
xxxxy
nxy
[root@localhost bash]# grep 'xx\+y' d.txt
xxy
xxxy
xxxxy
[root@localhost bash]# grep 'xxx\+y' d.txt
xxxy
xxxxy

 

  • \{m\}: 匹配其前面的字符m次;

  • 如下:可以自行理解下面的過程

[root@localhost bash]# cat d.txt
xy
xxy
xxxy
xxxxy
y
nxy
[root@localhost bash]# grep 'x\{2\}y' d.txt
xxy
xxxy
xxxxy
[root@localhost bash]# grep 'x\{1\}y' d.txt
xy
xxy
xxxy
xxxxy
nxy
[root@localhost bash]# grep 'x\{3\}y' d.txt
xxxy
xxxxy


  • \{m,n\}: 匹配其前面的字符至少m次,最多n次;

  •  如下:可以自行理解下面的過程

[root@localhost bash]# cat d.txt
xy
xxy
xxxy
xxxxy
y
nxy
[root@localhost bash]# grep 'x\{1,2\}y' d.txt
xy
xxy
xxxy
xxxxy
nxy
[root@localhost bash]# grep 'x\{2,4\}y' d.txt
xxy
xxxy
xxxxy
[root@localhost bash]# grep 'x\{3,5\}y' d.txt
xxxy
xxxxy

 

  • \{m,\}: 匹配其前面的字符至少m次,大於m次無限制;

  • 如下:可以自行理解下面的過程

[root@localhost bash]# cat d.txt
xy
xxy
xxxy
xxxxy
y
nxy
[root@localhost bash]# grep 'x\{2,\}y' d.txt
xxy
xxxy
xxxxy
[root@localhost bash]# grep 'x\{3,\}y' d.txt
xxxy
xxxxy
[root@localhost bash]# grep 'x\{4,\}y' d.txt
xxxxy
[root@localhost bash]# grep 'x\{5,\}y' d.txt
[root@localhost bash]#


  • .*: 匹配任意長度的字符

  • 如下:查找/etc/passwd文件中包含以"r"開頭以"t"結尾的字符串的行

[root@localhost bash]# grep 'r.*t' /etc/passwd
root:x:0:0:Administrator,1456,741,963:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
saslauth:x:498:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
user6:x:4009:4009::/tmp/user6:/bin/bash
user8:x:4010:4010::/home/user8:/bin/tcsh
user21:x:4012:4012::/tmp/user21:/bin/bash
gentoo:x:4021:4021::/users/gentoo:/bin/bash
centos:x:4022:4022::/users/centos:/bin/bash
 位置錨定:

 

  • ^: 錨定行首

  • 如下:查找/etc/passwd文件中以"r"開頭的行

[root@localhost bash]# grep '^r' /etc/passwd
root:x:0:0:Administrator,1456,741,963:/root:/bin/bash
rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin

 

  • $: 錨定行尾

  •  如下:查找/etc/passwd文件中以nologin結尾的行

[root@localhost bash]# 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
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
gdm:x:42:42::/var/lib/gdm:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
saslauth:x:498:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
pulse:x:497:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
pgsql:x:495:492::/home/pgsql:/sbin/nologin
nologin:x:4017:4017::/home/nologin:/sbin/nologin
mysql:x:4020:491::/home/mysql:/sbin/nologin
test:x:4023:4023::/home/test:/sbin/nologin

 

  • ^$: 錨定空白行

  • 如下:查找/etc/issue文件中的空白行

[root@localhost bash]# cat -n /etc/issue
     1    CentOS release 6.5 (Final)
     2    Kernel \r on an \m
     3    
     4    Mage Education Learning Services
     5    http://www.magedu.com
     6    
[root@localhost bash]# grep -n '^$' /etc/issue
3:
6:

 

  • \<或者\b: 錨定詞首

  • 如下:自行理解下面的過程

[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
root is 
what is your name?
Learn linux is fun.
Do you think so?
hasrootis
10 you think so?
100
hy root hehe
[root@localhost bash]# grep 'root' b.txt
root is 
hasrootis
hy root hehe
[root@localhost bash]# grep '\<root' b.txt
root is 
hy root hehe

 

  • \>或者\b: 錨定詞尾

  • 如下:自行理解分析下面的執行過程

[root@localhost bash]# vim b.txt
[root@localhost bash]# cat b.txt
hello world
hi jerry
my name is linux.
Hello world
root is 
what is your name?
Learn linux is fun.
Do you think so?
hasrootis
10 you think so?
100
hy roothehe
[root@localhost bash]# grep 'root' b.txt
root is 
hasrootis
hy roothehe
[root@localhost bash]# grep 'root\>' b.txt
root is


  • \<\>:錨定單詞

  • 如下:自行理解下面過程

[root@localhost bash]# cat b.txt
hello world
yourroot is hhi
hi jerry
my name is linux.
Hello world
root is 
what is your name?
Learn linux is fun.
Do you think so?
hasrootis
10 you think so?
100
hy roothehe
[root@localhost bash]# grep 'root' b.txt
yourroot is hhi
root is 
hasrootis
hy roothehe
[root@localhost bash]# grep '\<root\>' b.txt
root is


  • \|:或

  • 如下:搜索god或者good

[root@localhost bash]# cat n.tx
hi god ll
what good uuu
lsd oweur
oweu9r oweur 
hh ngodl ii
sdf sdf or
af ewgoode ee
[root@localhost bash]# grep 'god\|good' n.tx
hi god ll
what good uuu
hh ngodl ii
af ewgoode ee


  • \(\):分組

  • 如下:搜索n.tx中的"good"或者"gold"

[root@localhost bash]# cat n.tx
hi god ll
what good uuu
lsd oweur
oweu9r oweur 
i love gold
hh ngodl ii
sdf sdf or
af ewgoode ee
good is what?

[root@localhost bash]# grep 'go\(o\|l\)d' n.tx
what good uuu
i love gold
af ewgoode ee
good is what?
  後向引用:
  •   如果在模式中使用\(\)實現了分組,在文本檢查中,如果\(\)模式匹配到了某個內容,此內容後面的模式可以被引用;用\1引用第一個\(裏面的內容,用\2應用第二個\(裏面的內容,一次類推\3、\4 …….

  • 如下:查找m.txt中後面的名詞是前面動詞加r的行

[root@localhost bash]# cat m.txt 
I like a liker
I love a lover
I like a lover
I love a liker
[root@localhost bash]# grep 'l..e.*l..er' m.txt 
I like a liker
I love a lover
I like a lover
I love a liker
[root@localhost bash]# grep '\(l..e\).*\1' m.txt 
I like a liker
I love a lover


擴展正則表達式 

見名思義,可知是擴展的正則表達式,比基本正則表達式所支持的功能更多,在上面的基本正則表達式中大家可能最常見的就是"\"這個符號,這個符號就是轉義字符,除了單詞錨定的這個"\<\>"符號在擴展正則表達式不變,其餘的如果想用在擴展的正則表達式上的話,去掉"\"就行了,其餘的都不變,由於時間問題我在這裏就不廢話了,大家自己練習就行。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章