正则表达式

3 正则表达式

3.1、正则表达式基础

Linux Shell以一串字符作为表达式向系统传达意思。元字符(Metacharacters)是用来阐释字符表达式意义的字符,简言之,元字符就是描述字符的字符,它用于对字符表达式的内容、转换及各种操作信息进行描述。正则表达式是由一串字符和元字符构成的字符串,简称RE(Regular Expression)。正则表达式的主要功能是文本查询和字符串操作,它可以匹配文本的一个字符或字符集合。

正则表达式完成了数据的过滤,将不满足正则表达式定义的数据拒绝掉,剩下与正则表达式匹配的数据。

正则表达式的基本元素包括普通字符和元字符。POSIX标准将正则表达式分为两类:基本的正则表达式和扩展的正则表达式,大部分Linux应用和工具仅支持基本的正则表达式。

基本的正则表达式元字符集合及其意义:

* #0个或多个在*字符之前的那个普通字符

. #匹配任意字符

^ #匹配行首,或后面字符的非

$ #匹配行尾

[] #匹配字符集合

\ #转义符,屏蔽一个元字符的特殊意义

\ #精确匹配符号

\{n\} #匹配前面字符出现n次

\{n,\} #匹配前面字符至少出现n次

\{n,m\} #匹配前面字符出现n~m次

空行的表示方法: ^$

匹配只包含一个字符的行: ^.$

Linux系统对大小写是敏感的,并且支持字母排序,因此,Linux中有大写字母序列和小写字母序列,两者是分开的。

例:匹配字母

[a-z] #所有小写字母

[A-Z] #所有大写字母

[b-p] #小写字母b~p

“^”符号表示匹配行首,但是,“^”符号放到”[]”符号中就不再表示匹配行首了,而是表示取反符号。如:[^b-p]表示匹配不在b~p范围内的字符。

\正则表达式精确匹配the这个单词,而不匹配包含the字符的单词,如then。

3.2、正则表达式的扩展

除了正则表达式的元字符之外,awk和Perl等Linux工具还支持正则表达式扩展出来的一些元字符。

扩展的正则表达式元字符及其意义:

? #匹配0个或1个在其之前的那个普通字符

+ #匹配1个或多个在其之前的那个普通字符

() #表示一个字符集合或用在expr中

| #表示“或”,匹配一组可选的字符

3.3、通配

bash Shell本身不支持正则表达式,使用正则表达式的是Shell命令和工具,如grep、sed、awk等。但是,bash Shell可以使用正则表达式中的一些元字符实现通配(Globbing)功能,通配是把一个包含通配符的非具体文件名扩展存储在计算机、服务器或者网络上的一批具体文件名的过程。

例:列出以.awk结尾文件的详细信息

执行:ls -l *.awk

结果:-rwxrwxr-x 1 xiaomiao xiaomiao 59 8月 28 16:32 argv.awk

-rwxrwxr-x 1 xiaomiao xiaomiao 80 8月 28 16:17 array.awk

-rwxrwxr-x 1 xiaomiao xiaomiao 186 8月 28 16:45 findphone.awk

-rwxrwxr-x 1 xiaomiao xiaomiao 73 8月 28 15:19 pass.awk

-rwxrwxr-x 1 xiaomiao xiaomiao 50 8月 28 09:29 scr1.awk

-rwxrwxr-x 1 xiaomiao xiaomiao 77 8月 28 11:15 scr2.awk

-rw-rw-r-- 1 xiaomiao xiaomiao 36 8月 28 09:23 scr.awk

例:列出以a~h范围内字母开头,以.awk结尾的文件

执行:ls -l [a-h]*.awk

结果:-rwxrwxr-x 1 xiaomiao xiaomiao 59 8月 28 16:32 argv.awk

-rwxrwxr-x 1 xiaomiao xiaomiao 80 8月 28 16:17 array.awk

-rwxrwxr-x 1 xiaomiao xiaomiao 186 8月 28 16:45 findphone.awk

例:列出以g~h范围内字母开头,不以.awk结尾的文件

执行:ls -l [g-h]*.[^awk]*

结果:-rwxrwxr-x 1 xiaomiao xiaomiao 280 8月 17 17:16 getopts_exam1.sh

-rwxrwxr-x 1 xiaomiao xiaomiao 286 8月 17 17:15 getopts_exam1.sh~

-rwxrwxr-x 1 xiaomiao xiaomiao 466 8月 17 17:04 getopts_exam2.sh

-rwxrwxr-x 1 xiaomiao xiaomiao 466 8月 17 17:00 getopts_exam2.sh~ -rw-r--r-- 1 root root 2760 8月 23 14:32 gmond_msg_1.txt

-rwxrwxr-x 1 xiaomiao xiaomiao 364 8月 22 10:13 htmlconver2.sh

-rwxrwxr-x 1 xiaomiao xiaomiao 333 8月 22 09:52 htmlconver.sh

-rwxrwxr-x 1 xiaomiao xiaomiao 331 8月 22 09:51 htmlconver.sh~

例:列出匹配[a-c]*.awk或0?.pem的所有文件

执行:ls -l {[a-c]*.awk,0?.pem}

结果:ls: 无法访问0?.pem: 没有那个文件或目录

-rwxrwxr-x 1 xiaomiao xiaomiao 59 8月 28 16:32 argv.awk

-rwxrwxr-x 1 xiaomiao xiaomiao 80 8月 28 16:17 array.awk

注意,{}符号内的表达式是“或”的关系,即只要有{}符号内的一个表达式的文件,就能被列出。

通配的结果由计算机搜索大量的文件或者目录进行匹配而输出,通配对处理能力和内存资源有很高的需求。黑客输入包含通配符的文件名故意让服务器重复和连续不断地进行通配可能引起的拒绝服务攻击。因此,大型服务器经常通过限制服务器执行通配功能的次数、限制一个具体用户每次输入的通配符或者如果通配符太普通,则拒绝执行通配等方法来提高服务器的安全性。

内部变量GLOBIGNORE保存了通配时所忽略的文件名集合,?、*、[]、{}、^五个符号和GLOBIGNORE变量构成了Shell通配的所有内容。

3.4、grep命令

GREP是Global search Regular Expression and Print out the line的简称,即全面搜索正则表达式并把行打印出来。GREP是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。

3.4.1、grep命令基本用法

grep命令是支持正则表达式的一个多用途文本搜索工具,grep的一般格式为:

grep [选项] [模式] [文件...]

grep命令由选项、模式和文件三部分组成,它在一个或多个文件中搜索满足模式的文本行,模式后的所有字符串被看做文件名,文件名可以有多个,搜索的结果被打印到屏幕,不影响原文件的内容。Grep命令的选项用于对搜索过程进行补充说明。

grep命令选项及其意义:

-c #只输出匹配行的数量

-i #搜索时忽略大小写

-h #查询多文件时不显示文件名

-l #只列出符合匹配的文件名,而不列出具体的匹配行

-n #列出所有的匹配行,并显示行号

-s #不显示不存在或无匹配文本的错误信息

-v #显示不包含匹配文本的所有行

-w #匹配整词

-x #匹配整行

-r #递归搜索,不仅搜索当前工作目录,而且搜索子目录

-q #禁止输出任何结果,以退出状态表示搜索是否成功

-b #打印匹配行距文件头部的偏移量,以字节为单位

-o #与-b选项结合使用,打印匹配的词距文件头部的偏移量,以字节为单位

-E #支持扩展的正则表达式

-F #不支持正则表达式,按照字符串的字面意思进行匹配

grep命令的模式十分灵活,可以是字符串,也可以是变量,还可以是正则表达式。需要说明的是,无论模式是何种形式,只要模式中包含空格,就需要使用双引号将模式引起来,如果不加双引号,空格后的单词容易被误认为是文件名。大部分情况下,使用单引号将模式引起来也是可以的。

例:模式包含空格时,是否使用双引号的区别

WORDLIST文件的内容:

hello, caicai. world: watch, world caicai hello message

message world watch hello into the he she last into.

last save hello caicai, world: message.

#搜索WORDLIST文件中包含watch字符串的行,不需要引号引起模式

执行:grep watch WORDLIST

结果:hello, caicai. world: watch, world caicai hello message

message world watch hello into the he she last into.

#搜索WORDLIST文件中包含hello caicai字符串的行,不用引号将hello caicai引起

来的结果

执行:grep hello caicai WORDLIST

结果:grep: caicai: 没有那个文件或目录

#Shell将caicai解析为文件名,提示没有此文件的错误

#下面给出WORDLIST文件中包含hello字符串的行

WORDLIST:hello, caicai. world: watch, world caicai hello message

WORDLIST:message world watch hello into the he she last into.

WORDLIST:last save hello caicai, world: message.

#搜索WORDLIST文件中包含hello caicai字符串的行,用引号将hello caicai引起来

的结果

执行:grep "hello caicai" WORDLIST

结果:last save hello caicai, world: message.

例:grep的多文件查询

FILE1文件的内容:

Shanghai Jiaotong University

University of Toronto

Beijing University

Southeast University

Victory University

FILE2文件的内容:

Shanghai

Toronto

Beijing

Nanjing

Melbourne

执行:grep Beijing FILE1 FILE2

结果:FILE1:Beijing University

FILE2:Beijing

例:用通配表示多文件

执行:grep Beijing FILE?

结果:FILE1:Beijing University

FILE2:Beijing

1、-c选项

-c选项表示输出匹配字符串行的数量,默认情况下,grep命令打印出包含模式的所有行,一旦加上-c选项,就只显示包含模式行的数量。

例:grep -c的用法

执行:grep -c Beijing FILE?

结果:FILE1:1 #FILE1文件中有1行包含Beijing

FILE2:1

2、-n选项

-n选项列出所有的匹配行,并显示行号。默认情况下,grep搜索单个文件时,只显示每行的内容,搜索多个文件时,显示文件名及每行的内容,加上-n选项后,将在行内容前附加显示行号。

例:grep -n的用法

执行:grep -n Beijing FILE?

结果:FILE1:3:Beijing University #FILE1文件的第3行

FILE2:3:Beijing

3、-v选项

-v选项显示不包含模式的所有行。

例:grep -v的用法

执行:grep -vc Beijing FILE? #同时使用-v和-c选项

结果:FILE1:4 #FILE1文件中有4行不包含Beijing字符串

FILE2:4

4、-i选项

默认情况下,grep命令对大小写是敏感的,如果加上-i选项就表示grep命令不区分大小写。

5、-h选项

-h选项表示查询多文件时不显示文件名,默认情况下,grep命令查询多个文件时,在匹配行之前显示文件名,加上-h选项后,grep命令将不再显示文件名。

例:grep -h的用法

执行:grep -h Beijing FILE?

结果:Beijing University #在匹配行前不再显示文件名了

Beijing

6、-l选项

-l选项表示只列出符合匹配的文件名,而不列出具体匹配行。

例:grep -l的用法

执行:grep -l Beijing FILE?

结果:FILE1 #只显示包含Beijing字符串的文件名

FILE2

7、-s选项

-s选项表示不显示不存在或无匹配文本的错误信息,默认情况下,grep在待搜索文件不存在或搜索不到符合模式的文本行时将打印错误信息。

例:grep -s的用法

执行:grep hello caicai WORDLIST #未使用-s选项

结果:grep: caicai: 没有那个文件或目录 #打印了错误信息

WORDLIST:hello, caicai. world: watch, world caicai hello message

WORDLIST:message world watch hello into the he she last into.

WORDLIST:last save hello caicai, world: message.

执行:grep -s hello caicai WORDLIST #使用-s选项后,不打印错误信息

结果:WORDLIST:hello, caicai. world: watch, world caicai hello message

WORDLIST:message world watch hello into the he she last into.

WORDLIST:last save hello caicai, world: message.

8、-r选项

默认情况下,grep命令只对当前目录下的文件进行搜索,而不对子目录中的文件进行搜索。-r选项表示递归搜索,不仅搜索当前目录,而且搜索子目录。

9、-w和-x选项

grep命令的模式是支持正则表达式的,正则表达式的元字符将被解释成特殊的含义,-w选项表示匹配整词,即以模式的字面含义去解析它。因此,grep命令使用-w选项后,元字符不再被解释为特殊含义。

例:grep -w的用法

执行:grep hell* WORDLIST #搜索包含以hell开头字符串的文本行

结果:hello, caicai. world: watch, world caicai hello message

message world watch hello into the he she last into.

last save hello caicai, world: message.

#加上-w选项后,表示搜索包含hell*字符串的文本行

执行:grep -w hell* WORDLIST

结果:

-x选项是匹配整行,即只有当文件中有整行内容与模式匹配时,grep命令才输出该行结果。

例:说明grep命令的-w和-x选项的区别

world.txt文件的内容:

Hello World

World

World Cup

African

One One World

执行:grep -w 'World' world.txt #搜索包含单词“World”的文本行

结果:Hello World #所有包含单词“World”的文本行都被输出

World

World Cup

One One World

执行:grep -x 'World' world.txt #搜索整行文本是单词“World”的行

结果:World #只有此行满足条件

10、-q选项

grep命令默认情况下是输出结果的,但是,grep命令后一旦加上-q选项,grep将不再输出任何结果,而是以退出状态表示搜索是否成功,退出状态0表示搜索成功,退出状态1表示未搜索到满足模式的文本行,退出状态2表示命令或程序由于错误而未能执行。

例:grep -q选项的用法

执行:grep -q -x 'World' world.txt #grep命令搜索成功

echo $?

结果:0

执行:grep -q -x 'World African' world.txt #grep命令未搜索到满足模式的文本行

echo $?

结果:1

执行:grep -q -x 'World African' world #grep命令执行失败

结果:grep: world: 没有那个文件或目录

执行:echo $?

结果:2

11、-b和-o选项

grep -b选项打印匹配行距文件头部的偏移量,以字节为单位。如果在-b选项后再加上-o选项,grep命令将打印匹配的词距文件头部的偏移量。

例:grep命令的-b和-o选项的用法

执行:grep -b -w 'World' world.txt #打印匹配行距文件头部的偏移量

结果:0:Hello World

12:World

18:World Cup

36:One One World

执行:grep -b -o -w 'World' world.txt #打印匹配词距文件头部的偏移量

结果:6:World

12:World

18:World

44:World

grep命令的-E和-F选项分别等价于grep命令族中的egrep和fgrep命令。

3.4.2、grep和正则表达式结合使用的一组例子

将带元字符的正则表达式用于grep命令能够更灵活地匹配信息,使用时需要使用单引号将正则表达式引起来,以免发生一些不可预知的错误。

1、匹配行首

元字符“^”表示行首,“^$”符号表示空白行范围,而要匹配文件中非空白行时则使用“^[^$]”符号表达式,“^^$”表达式是错误的。

2、设置大小写

利用-i符号可以使grep命令不区分大小写,当然也可利用[]符号来实现这一功能。

例:用[]符号设置大小写

output文件的内容:

/O=Grid/OU=GlobusTest/OU=simpleCA-seugrid1.seu.edu.cn/OU=seu.edu.cn/CN=globus /home/globus/.globus/usercert.pem

执行:grep -n [Gg]lobus output

结果:1: /O=Grid/OU=GlobusTest/OU=simpleCA-seugrid1.seu.edu.cn/OU=seu.edu.cn/CN=globus

2:/home/globus/.globus/usercert.pem

3、匹配重复字符

匹配重复字符通常可以利用“ . ”符号和“ * ”符号来实现。

例:grep和 . 符号

#匹配以W字符开始、中间3个任意字符、第5个字符未d的行

执行:grep ^W...d world.txt

结果:World

World Cup

例:grep和*符号

#匹配以“0”开头,重复“0”符号任意次,然后是W字符的行

执行:grep ^0*W world.txt

结果:World #表示“0”符号重复0次,仍然符合“*”符号的语法

World Cup

4、转义符

如果匹配的目标字符串中包含元字符,则需要利用转义字符“\”屏蔽其意义。

例:grep和转义符

执行:grep seu\.edu\.cn output

结果: /O=Grid/OU=GlobusTest/OU=simpleCA-seugrid1.seu.edu.cn/OU=seu.edu.cn/CN=globus

如果将命令写成 grep 'seu.edu.cn' output 则是匹配seu和edu、edu和cn之间存在任意单个字符的行,如seuxeduxcn能够满足条件。

横杠(-)字符较为特别,它虽然不属于正则表达式元字符,但是,由于“-”字符是引出grep命令选项的特殊字符,所以,模式以“-”符号开头时,需要用转义字符将其转义。

例:-字符在grep命令中的特殊性

test1.txt文件的内容:

-----BEGIN CERTIFICATE REQUEST-----

-----END CERTIFICATE REQUEST-----

BAIwADANBgkqhkiG9

执行:grep -\{5\} test1.txt #模式以-符号开头

结果:grep:无效选项 -- { #提示错误,grep将模式解析为选项

用法: grep [选项]... PATTERN [FILE]...

试用‘grep --help’来获得更多信息。

执行:grep '-\{5\}' test1.txt #将模式用引号括起来也解决不了问题 结果:grep:无效选项 -- \

用法: grep [选项]... PATTERN [FILE]...

试用‘grep --help’来获得更多信息。

执行:grep '\-\{5\}' test1.txt

结果:-----BEGIN CERTIFICATE REQUEST-----

-----END CERTIFICATE REQUEST-----

执行:grep \-\{5\} test1.txt #模式不用引号括起来

结果:grep:无效选项 -- {

用法: grep [选项]... PATTERN [FILE]...

试用‘grep –help’来获得更多信息。

注意,这里模式上的引号十分重要,如果不加引号,仍然提示无效选项错误。

5、POSIX字符类

为了保持不同国家的字符编码的一致性,POSIX(Portable Operating System Interface)增加了特殊的字符类,以[:classname]的格式给出,grep命令支持POSIX字符类。

POSIX字符类:

[:upper:] #表示大写字母[A~Z]

[:lower:] #表示小写字母[a~z]

[:digit:] #表示阿拉伯数字[0~9]

[:alnum:] #表示大小写字母和阿拉伯数字[0~9 a~z A~Z]

[:space:] #表示空格或Tab键

[:alpha:] #表示大小写字母[a~z A~Z]

[:cntrl:] #表示Ctrl键

[:graph:]或[:print:] #表示ASCII码33~126之间的字符

[:xdigit:] #表示16进制数字[0~9 A~F a~f]

例:搜索以空格开头的文本行

执行:grep ^[[:space:]] output

结果: /O=Grid/OU=GlobusTest/OU=simpleCA-seugrid1.seu.edu.cn/OU=seu.edu.cn/CN=globus

POSIX字符类作为模式的用法都类似,使用时只要注意用方括号将POSIX字符类括起来即可。

6、精确匹配

例:精确匹配

re01文件的内容:

Line1:there are four lines in this file

Line2:this the line 2

Line3:this is another line

Line4:this is line4

执行:grep the re01 #列出所有包含the字符串的行 结果:Line1:there are four lines in this file #there中包含了the

Line2:this the line 2

Line3:this is another line

执行:grep "\" re01 #精确匹配the这个单词

结果:Line2:this the line 2

执行:grep -w the re01 #利用-w选项实现精确匹配

结果:Line2:this the line 2

注意,\上的引号必不可少。

7、或字符

或字符“|”是扩展的正则表达式中定义的,grep需要加上-E选项才能支持它。

例:grep命令与 | 字符

执行:grep -E "four|another" re01 #带-E选项的grep执行成功

结果:Line1:there are four lines in this file

Line3:this is another line

执行:grep "four|another" re01

结果:

grep没有带-E选项时,返回结果为空,这是因为grep命令将“|”字符解析为字面意义。注意,four|another上的引号必不可少。

3.4.3、grep命令族简介

Linux系统支持三种形式的grep命令,通常将这三种形式的grep命令称为grep命令族,这三种形式具体为:

grep:标准grep命令,支持基本正则表达式。

egrep:扩展grep命令,支持基本和扩展正则表达式。

fgrep:快速grep命令,不支持正则表达式,按照字符串的字面意思进行匹配。

egrep命令与grep -E等价,fgrep命令与grep -F等价,在某些Linux发行版中,egrep和fgrep都是grep命令的别名,分别将其符号链接到grep -E和grep -F命令。

例:egrep命令的用法

执行:egrep "four|another" re01

结果:Line1:there are four lines in this file

Line3:this is another line

执行:egrep ^-*B test1.txt

结果:-----BEGIN CERTIFICATE REQUEST-----

BAIwADANBgkqhkiG9

执行:egrep ^-+B test1.txt

结果:-----BEGIN CERTIFICATE REQUEST-----

注意“^-*B”和“^-+B”的区别,“+”符号表示“-”符号至少重复一次,不匹配以B字符开头的行。

例:fgrep命令的用法

执行:fgrep ^-*B test1.txt #fgrep命令不支持正则表达式 结果:

执行:fgrep BEGIN test1.txt #fgrep命令支持普通字符串

结果:-----BEGIN CERTIFICATE REQUEST-----


© 2024 实用范文网 | 联系我们: webmaster# 6400.net.cn