在CentOS6系统中使用grep命令结合正则表达式搜索文本行

10章 正则表达式

10.1 正则表达式基础

10.1.1 什么是正则表达式

正则表达式就是能用某种模式去匹配一类字符串的公式,它是由一串字符和元字符构成的字符串。

10.1.2 基础的正则表达式 

“.”(一个点)符号

点符号用于匹配除换行符之外的任意一个字符。例如:r.t可以匹配rot、rut,但是不能匹配root,
若使用r..t就可以匹配root、ruut、r  t(中间是两个空格)等。

例:从/etc/passwd中搜索出“包含r,紧跟着两个字符,后面再接t”的行。

[kangyp@centos6 Documents]$ grep 'r..t' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
[kangyp@centos6 Documents]$ 

“*”符号

“*”符号用于匹配前一个字符0次或任意多次,比如ab*,可以匹配a、ab、abb等。
“*”号经常和“.”符号加在一起使用。比如“.*”代表任意长度的不包含换行的字符。

例:‘r.*t’,代表查找包含字母r,后面紧跟任意长度的字符,再跟一个字母t的行。 

“\{n,m\}”符号

\{n\}匹配前面的字符n次。
例:匹配的是包含root的行(r和t中包含两个o)

[kangyp@centos6 Documents]$ grep 'ro\{2\}t' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[kangyp@centos6 Documents]$ 

\{n,\}匹配前面的字符至少n次以上(含n次)

例:匹配的是包含rt、rot、root……的行

[kangyp@centos6 Documents]$  grep 'ro\{0,\}t' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
rtkit:x:499:499:RealtimeKit:/proc:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
[kangyp@centos6 Documents]$ 

\{n,m\}匹配前面的字符nm次。

“^”符号

这个符号位于键盘数字6的上面,又称尖角号。这个符号用于匹配开头的字符。
比如说“^root”匹配的是以字母root开始的行。

“$”符号

“$”用于匹配尾部,比如说“abc$”代表的是以abc结尾的行。
如果是“^$”则代表该行为空,因为^和$间什么都没有。

例:匹配的是以r开头,中间有一串任意字符,以h结尾的行。

[kangyp@centos6 Documents]$ grep '^r.*h$' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[kangyp@centos6 Documents]$ 

“[]”符号

这是一对方括号,用于匹配方括号内出现的任一字符。比如说单项选择题的答案,可能是A、B、C、D选项中的任意一种,用正则表达式表示就是[ABCD]。
如果遇到比较大范围的匹配,比如说要匹配所有字母则写成[A-Za-z],此处要使用“-”号做范围限定。

如果是要匹配不是大写字母A、B、C、D的字符又该怎么写呢?还记得上面的“^”号吗,如
果这个符号出现在[]中,则代表取反,也就是“不是”的意思。那这里的写法就是[^A-D]

“\”符号

这个符号代表转义字符,我们可以对很多特殊的字符进行“转义”,让它只代表字符本身

例:如果想要匹配任意长度的点号呢?
这时使用转义字符就对了:“\.*”

“\<”符号和“\>”符号

这两个符号分别用于界定单词的左边界和右边界。比如说“\<hello”用于匹配以“hello”开头的单词;而“hello\>”则用于匹配以“hello”结尾的单词。
还可以使用它们的组合——“\<\>”用于精确匹配一个字符串。所以“\<hello\>”可精确匹配单词hello,而不是helloworld等。

[root@localhost ~]# echo "hello" | grep '\<hello\>'
hello
[root@localhost ~]# echo "hellod" | grep '\<hello\>'
[root@localhost ~]# #没有输出,表示匹配不成功

 

以上讲的是8种常见的元字符 

“\d”符号

匹配一个数字,等价于[0-9] ,使用grep匹配这种正则表达式时可能会遇到无法匹配的问题。

这是因为“\d”是一种Perl兼容模式的表达式,又称作PCRE,要想使用这种模式的匹配符,需要加上-P参数,示例如下:

[root@localhost ~]# echo 123 | grep -P '\d'
123 #
这样就匹配成功了

“\b”符号

匹配单词的边界,比如“\bhello\b”可精确匹配含有“hello”单词的行。

“\w”符号

匹配字母、数字和下划线,等价于[A-Za-z0-9]

 

“\n”符号
匹配一个换行符。

“\r”符号
匹配一个回车符。

“\t”符号
匹配一个制表符。

“\f”符号
匹配一个换页符。

“\s”符号

匹配任何空白字符。

“\S”符号
匹配任何非空白字符。

10.1.3 扩展的正则表达式

在使用这些扩展符号时,需要使用egrep命令。

“?”符号

“?”符号用于匹配前一个字符0次或1次,所以“ro?t”仅能匹配rot或rt。

“+”符号

“+”符号用于匹配前一个字符1次以上,所以“ro+t”就可以匹配rot、root等。

“|”符号

“|”符号是“或”的意思,即多种可能的罗列,彼此间是一种分支关系。

“()”符号

“()”符号通常需要和“|”符号联合使用,用于枚举一系列可替换的字符。
比如说固定电话的区号和电话号码之间,可能用“-”符号或者用一个空格连接。

^0[0-9]\{2,3\}(-| )[0-9]\{8\}

使用"()"和"|"匹配hard、hold或hood

h(ar|oo|ol)d

 

10.1.4 通配符

通配符是一种特殊的语句,主要包含“*”号和“?”号(还有“{}”、“^”、“!”)
主要用来模糊搜索文件,使用它替代一个或多个真正的字符,尤其是在不知道或者不确定完整的文件名时,用来匹配符合条件的文件。

“*”符号

这里的“*”就是提到的第一个通配符,代表0个或多个字符。
那么之前的*.doc就是指所有以.doc结尾的文件。如果想要找的文档是以字母A开头,则可用A*.doc来查找。

“?”符号

当它作为通配符使用时,代表的是任意一个字符。

“{}”符号

“{}”可拥有匹配所有括号内包含的以逗号隔开的字符。
例如,下面列出了所有以字母A、B、C开头,以.doc结尾的文件:
[root@localhost ~]# ls -l {A,B,C}.doc

有 意 思 的 是 , “{}” 还 支 持 嵌 套 的 通 配 。
[root@localhost ~]# ls -l {[A-Z]*.doc,[0-9]??.txt}

“^”符号和“!”符号

这两个符号往往和“[]”一起使用,当出现在“[]”中的时候,代表取反。

10.2 正则表达式示例

在前面的第5章中,我们了解了grep的一些基本用法,但是它的功能还远远不止这些。
grep的 英 文 是 Global search Regular Expression and Print out the line,即全面搜索正则表达式并打印出匹配行。通过本章前面的一些实例我们也看到,grep和正则表达式结合使用后产生了强大的搜索效果。
提醒一下读者,由于正则表达式中含有较多特殊的字符,所以结合grep时,最好使用单引号将正则表达式括起来,以免造成错误。

为了演示grep命令的用法,首先创建一个文件RegExp.txt,文件内容如下所示:

----TEXT BEGIN----
good morning teacher
hello world is a script
gold sunshine looks beautiful
golden time flies
god bless me


what a delicious food
they teast Good
you fell glad
wrong word gooood
wrong word gl0d
wrong word gl2d
wrong word gl3d
www.helloworld.com
www@helloworld@com
Upper case
100% means pure
php have a gd module
-----TEXT END-----

1)使用“^”匹配行首,示例如下:
#搜索以good开头的行

grep '^good' RegExp.txt

2)使用“$”匹配行尾,示例如下:
#搜索以Good结尾的行

grep 'Good$' RegExp.txt

3)使用“^$”组合,匹配空行,下面的命令可计算文件中共有多少行空行:

grep -c '^$' RegExp.txt

4)使用方括号匹配多种可能,示例如下:
#搜索包含Good和good的行

grep '[Gg]ood' RegExp.txt

5)在方括号中使用“^”做反选,示例如下:
#搜索一个包含ood的行,但是不能是Good或good

grep '[^Gg]ood' RegExp.txt

6)使用“.”号,示例如下:
#搜索包含一个词,该词以g开头、紧接着是两个任意字符、再接着是一个d的行

grep 'g..d' RegExp.txt

#搜索包含一个词,该词以G或g开头、紧接着是两个任意字符、再接着是一个d的行

grep '[Gg]..d' RegExp.txt

#搜索这样一些行,该行包含某个单词,该词满足如下条件:
#1.
第一个字符可以是G或g
#2.
第二个字符可以是l或o
#3.
第三个字符可以是换行符之外的任意字符
#4.
第四个字符一定是d

grep '[Gg][lo].d' RegExp.txt

7)使用精确匹配,示例如下:
#搜索含有gold的行,从搜索结果中发现golden也被匹配出来了
#现在我们需要精确匹配含有gold这个单词的行

grep '\<gold\>' RegExp.txt

# 用“\b”的效果和“\<\>”一致

grep '\bgold\b' RegExp.txt

8)使用“*”号,示例如下:
#
搜索这样一些行,该行包含某个单词,该词满足如下条件:
#1.以g开头
#2.g后面跟零到无限个o
#3.零到无限个o后面跟d

grep 'go*d' RegExp.txt

10)使用“-”号,示例如下:
#
文件中有一些拼写错误的单词,发现是把glod中的o字母写成数字0了

grep 'gl[0-9]d' RegExp.txt

11)使用“\”做字符转义,示例如下:
#搜索文件中包含域名www.helloworld.com的行
#这里将点做转义,则输出的结果满足预期

grep 'www\.helloworld\.com' RegExp.txt

12)使用“\{\}”号,示例如下:
#
文档中有一个单词good被拼写错了,多写了几个o
#
搜索以字母g开头包含两个以上o的单词

grep 'go\{2,\}d' RegExp.txt

#
搜索以字母g开头,中间正好包含4个o的单词

grep 'go\{4\}' RegExp.txt

13)特殊的POSIX字符,示例如下:
#grep支持一类特殊的POSIX字符,列举如下
#[:upper:]
大写字符
#[:lower:]
小写字符
#[:digit:]
数字字符
#[:space:]
所有空白字符(新行,空格,制表符)
#[:print:]
非空字符(包括空格)
#[:punct:]
标点符号

#搜索以大写字母开头的行
grep ^[[:upper:]] RegExp.txt
#搜索以数字开头的行
grep ^[[:digit:]] RegExp.txt

14)使用扩展的正则表达式egrep,示例如下:
#
搜索g和d之间至少有一个o的行

egrep 'go+d' RegExp.txt

#搜索g和d之间只有0个或1个o的行(0次或1次)

egrep 'go?d' RegExp.txt

#
搜索有glad或gold的行

egrep 'glad|gold' RegExp.txt

#
搜索有glad或gold的行的另一种写法

egrep 'g(la|ol)d' RegExp.txt

只有不断地多读多用,才能较为深刻地理解正则表达式。 

 

参考资料:

Linux系统命令及Shell脚本实践指南:10章 正则表达式

posted @ 2020-10-24 19:11  Marlon康  阅读(375)  评论(0编辑  收藏  举报