首页 > 代码库 > 正则表达式第一关之grep

正则表达式第一关之grep

 

    很多学linux的同学和我一样,鸟哥的私房菜里每次读到正则表达式那一章,就感觉缺乏攻破它的勇气了,如果你和我一样也是刚进入linux世界的菜鸟,不妨多总结里面的基本用法以及一些特别需要注意的地方,相信你和我一样,不妨多反复揣摩,相信你也可以熟练掌握它,所谓书读百变起义自现。

   刚接触的你肯定会疑问什么是正则表达式(Regular Expression),简单的讲正则表达就是处理字符串的方法,有点像word里的查找替换,不过它可比word里的查找替换强大N倍,它是以行为单位来进行字符串处理行为,通过一些特殊符号的辅助,轻松的帮你查找、删除、替换某些特定字符串的处理程序。下面让我们一起去攻破正则表达的第一个命令grep。 

   

   本文的主要内容包括以下内容:

 

    1.什么是grep命令

    2.grep命令格式及说明

    3.常用选项及示例

    4.匹配模式之正则表达式

    5.匹配模式之扩展正则表达式

    6.总结

 

一、什么是grep命令

    grep(global search regular expression_r(RE) and print out theline),这是我们接触到的第一个文本搜索工具,之前我们就说过正则表达式是对行进行操作的,所以grep也是根据我们指定的文本模式对目标文件进行逐行进行搜索,显示能够被模式所匹配到的行。简单点说呢,就是给grep命令一个模板,它会按照这个模板在文本里一行一行的扫描你想要的内容,搜索到的结果被直接送到你的屏幕上,不影响原文件内容,当然我们也可以通过管道重定向等方式进行其他包括替换删除等操作再送到你的屏幕上,也可以保存到文件里,而原文件可以保持不变。Egrepgrep -E)、fgrep(fgrep ‘PATTERN‘ FILE...不支持正则表达式)与之相近,均可以通过grep命令与不同的选项组合实现,因此在本文中,我们不再进行过多描述。

 

二、grep命令格式及说明

 

   格式:grep [options] ‘PATTERN’ file,…

   说明:PATTERN是搜索文本的关键,grep用PATTERN正则表达式来搜索文本中的每一行,在贪婪的模式下(命令尽可能多的匹配行内的字串),尽力去匹配。

 

三、常用选项及示例

 

--color=auto  -n

将搜索出的符合条件的行的匹配上的字符自动着色显示;显示行号

-v

反向查找,显示出不能被模式匹配到的行

-E

支持扩展正则表达式

-i

不区分字符大小写

-o

仅显示被模式匹配到的字串,而非整行

-A #

显示被匹配到的行,包括它之后的#行(#表示正整数)

-B #

显示被匹配到的行,包括它之前的#行(#表示正整数)

-C #

显示被匹配到的行,包括它前后的#行(#表示正整数)

   示例

   1.-n 显示文本所在的行号,搜索以nologin结尾的行。

1

2

3

4

[root@localhost~]# grep --color=auto -n "nologin$" /etc/passwd

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

 

   2.-v 反向显示。显示不是以nologin为结尾的行

 

1

2

3

4

5

[root@localhost~]# grep --color=auto -n -v  "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

 

   3.-i 不区分大小写。显示以root为开头的行。

 

1

2

3

[root@localhost~]# grep --color=auto -i "^root" /etc/passwd

root:x:0:0:root:/root:/bin/bash

Root:x:500:500::/home/Root:/bin/bash

 

   4.-o 只显示匹配的字串,而不是整行。显示以root开头的行

 

1

2

3

[root@localhost~]#  grep --color=auto -o "^root" /etc/passwd

root

[root@localhost~]#

 

   5.-A # 显示匹配到行的后#行。搜索以ftp开头的行

 

1

2

3

4

5

6

[root@localhost~]# grep --color=auto -A 3 "^ftp" /etc/passwd

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

[root@localhost~]#

 

   6.-B # 显示匹配到行的前#行。搜索以ftp开头的行

 

1

2

3

4

5

6

[root@localhost~]# grep --color=auto -B  3 "^ftp" /etc/passwd

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

[root@localhost~]#

 

四、匹配模式之基本正则表达式

 

   在grep命令格式中的PATTERN正则表达式是重点和难点。学好正则表达式,“走遍天下都不怕”,在vim的末行模式等场景下,正则表达式都有出色的表现。这里总结正则表达式元字符(不表示字符本身的意义,用于额外功能性的描述)。并辅以实例说明。在原元字符中经常可以看到的\,是转义符。在扩展正则表达式中是不需要的。

 

   1.字符匹配

 

.

任意单个字符

[]

指定范围内的任意单个字符,

[0-9], [[:digit:]]

[a-z], [[:lower:]]

[A-Z], [[:upper:]]

[[:alpha:]]

[[:alnum:]]

[[:space:]]

[[:punct:]]   类似通配符里的内容

[^]

指定范围外的任意单个字符

   此处建立实验用文本test.txt,test1.txt内容为  

1

2

3

4

5

6

7

#test.txt

abc

abcd

aaaa

acdgssd

sddes

dseega

 

   1-1 . 匹配任意单个字符。

 

1

2

3

4

[root@localhost~ ~]# grep --color=auto "a.c" /tmp/test.txt

abc

abcd

[root@localhost~]#

   注:这里要匹配到a与c中间有一个任意字符的行

 

   1-2 []指定范围内的任意字符。查找所有包含s或g的字串

 

1

2

3

4

5

[root@localhost~]# grep --color=auto "[sg]" /tmp/test.txt

acdgssd

sddes

dseega

[root@localhost~]#

 

   注:这里查找到了,a或者b开头的行,[ab]二者选其一。其他类似,不再一一列举。

 

   1-3 [^] 指定范围外的任意单个字符。搜索不包含a的字串

 

1

2

3

4

5

6

7

[root@localhost~]# grep --color=auto "[^a]" /tmp/test.txt

abc

abcd

acdgssd

sddes

dseega

[root@localhost~]#

 

    2.次数匹配

 

   此处的匹配的次数指的是元字符前面的那个字符。

 

*

匹配其前面的字符任意次

\?

匹配其前面的字符0次或1次

\{m\}

匹配其前面的字符匹配m次

\{m,n\}

匹配其前面的字符至少m次,至多n次

\{m,\}

匹配其前面的字符至少m次

\{0,n\}

匹配其前面的字符至多n次

   实验文本test1.txt

 

1

2

3

4

5

#test1.txt

xxy

xy

y

xxy

   2-1 *  任意次数。

 

1

2

3

4

5

6

[root@localhost~]# grep --color "x*y" test1.txt

xxy

xy

y

xxy

[root@localhost~]#

 

   注:y前面可以出现任意个x,包括0个

 

   2-2 \? 0次或1次

 

1

2

3

4

[root@localhost~]# grep --color "roo\?t" /etc/passwd

root:x:0:0:root:/root:/bin/bash

operator:x:11:0:operator:/root:/sbin/nologin

[root@localhost~]#

   注:root,o出现了一次

 

   2-3 \{m\}匹配m次。

 

 

1

2

3

4

[root@localhost ~]# grep --color "ro\{2\}t" /etc/passwd

root:x:0:0:root:/root:/bin/bash

operator:x:11:0:operator:/root:/sbin/nologin

[root@localhost ~]#

 

 

   注:出现两次o

 

   2-4 \{m,n\}至少m次,至多n次

 

1

2

3

4

5

[root@localhost~]# grep --color "x\{1,2\}y" test1.txt

xxy

xy

xxy

[root@localhost~]#

 

   注:这里,x最少出现一次,最多出现了2次

 

   2-5 \{m,\}至少m次

 

1

2

3

4

5

[root@localhost ~]# grep --color "x\{1\}y" test1.txt

xxy

xy

xxy

[root@localhost ~]#

 

 

    注:至少出现1次,因此y那一行由于是0次没有显示出来

 

   2-6 \{0,n\}至多n次

 

1

2

3

4

[root@localhost ~]# grep --color "x\{2\}y" test1.txt

xxy

xxy

[root@localhost~ ~]#

 

 

     注:最多出现2次x

 

   3.位置锚定

 

   位置锚定是通过一定的格式,将一些字符或者字符串固定在想要的位置上。

 

^

锚定行首

$

锚定行尾

^$

空白行

\<

锚定词首

\>

锚定词尾

   演示用文本

 

1

2

3

4

5

6

xxy

xy

y

xxy

axyxyb

abc

 

   3-1 ^ 锚定词首。显示以root开头的行。

 

1

2

3

[root@localhost~]# grep --color "^root" /etc/passwd

root:x:0:0:root:/root:/bin/bash

[root@localhost~]#

 

 

   注:以root为行首的行

 

 

    3-2 $ 锚定词尾。显示以bash为词尾的行

 

1

2

3

4

5

6

7

8

[root@localhost~]# grep --color "bash$" /etc/passwd

root:x:0:0:root:/root:/bin/bash

Root:x:500:500::/home/Root:/bin/bash

testuser:x:501:501::/home/testuser:/bin/bash

user1:x:502:502::/home/user1:/bin/bash

Badguy:x:503:503::/home/Badguy:/bin/bash

Creayboy:x:504:504::/home/Creayboy:/bin/bash

[root@localhost~]#

 

   3-3 ^$ 不显示空白行。

 

1

2

3

4

5

6

7

[root@localhost~]# grep --color -v "^$" test1.txt

xxy

xy

y

xxy

abc

[root@localhost~ ~]#

 

 

    注:此处使用了反向显示。

 

   3-4 \<锚定词首

 

1

2

3

[root@localhost~]# grep --color=auto "\<xy" test1.txt

xy

[root@localhost~ ~]#

 

 

    若不锚定词首,则会出现下面的结果

 

1

2

3

4

5

6

[root@localhost~]# grep --color=auto "xy" test1.txt

xxy

xy

xxy

axyxyb

[root@localhost~ ~]#

 

    3-5 锚定词尾

 

1

2

3

4

5

[root@localhost~]# grep --color=auto "xy\>" test1.txt

xxy

xy

xxy

[root@localhost~]#

 

 

     若不锚定词尾

 

1

2

3

4

5

6

[root@localhost ~]# grep --color=auto "xy" test1.txt

xxy

xy

xxy

axyxyb

[root@localhost ~]#

 

   4.分组显示

 

 

\(\)

eg:\(ab)\*xy

    如上实例,将ab做为一个分组,以组合的形式出现。在下面的引用中,做实例

 

   5.引用

 

\1

后向引用。eg:\(a.b\)xy\1可以匹配到a6bxya6b

\2

多次后向引用,后面的数字可增大

 

   示例用文本

 

1

2

3

4

5

#test2.txt

He like his lover.

She love her liker.

He love his lover.

She like her liker.

 

   找出like对应liker,love对应lover的行

 

1

2

3

4

[root@localhost~]# grep --color=auto "\(l..e\).*\1r" test2.txt

    He love his lover

    She like her liker

[root@localhost~]#

   注:这里,使用了后向引用和分组。将l..e固定为一个组,然后后向引用。

 

五、匹配模式之扩展正则表达式

 

   扩展正则表达式与基本正则表达式十分相似,二者最主要的区别就是扩展正则表达式不使用转义字符。下面是二者元字符的对比表

 

字符匹配

基本正则表达式

扩展正则表达式

说明

.

.

任意单个字符

[]

[]

指定范围内的任意单个字符

[^]

[^]

指定范围外的任意单个字符

 

次数匹配

基本正则表达式

扩展正则表达式

说明

*

*

匹配其前面的字符任意次

\?

?

匹配其前面的字符0或1次

\{m\}

{m}

匹配其前面的字符m次

\{m,n\}

{m,n}

匹配其前面的字符至少m次,至多n次

\{m,\}

{m,}

匹配其前面的字符至少m次

\{0,n\}

{0,n}

匹配其前面的字符至多n次

----

+

匹配其前面的字符至少1次

 

位置锚定

基本正则表达式

扩展正则表达式

说明

^

^

锚定行首

$

$

锚定行尾

\<, \b

\<, \b

锚定词首

\>, \b

\>, \b

锚定词尾

 

分组

基本正则表达式

扩展正则表达式

说明

\(\)

()

分组

扩展正则表达式与基本正则表达式类似,因此不再给出示例。

 

六、结语

 

   grep是文本搜索的利器,刚开始还是需要对其最基本的用法熟练于心,在bash的学习中,你会经常用到它,所以更多grep的高级用法在那边会体现出正则表达的强大功能,通过不断的练习,你会攻破学习linux路上正则表达式的第一关grep相关的运用技巧,其实在后期的总结中,你会发现我们菜鸟最最头疼的是那些符号的不确定,其实我们对最基本的东西还不是很熟练的所导致的,所以多总结多练,你可以的,JUST DO IT!