前言
正则表达式应用广泛,在绝大多数的编程语言都可以完美应用,在Linux中,也有着极大的用处。
使用正则表达式,可以有效的筛选出需要的文本,然后结合相应的支持的工具或语言,完成任务需求。
在本篇博客中,我们使用grep/egrep来完成对正则表达式的调用,其实也可以使用sed等工具,但是sed的使用极大的需要正则表达式,为了在后面sed篇的书写,就只能这样排序了,有需要的朋友可以把这两篇一起来看。
正则表达式的类型
正则表达式可以使用正则表达式引擎实现,正则表达式引擎是解释正则表达式模式并使用这些模式匹配文本的基础软件。
在Linux中,常用的正则表达式有:
- POSIX 基本正则表达式(BRE)引擎
- POSIX 扩展正则表达式(BRE)引擎
基本正则表达式的基本使用
环境文本准备
[root@service99 ~]# mkdir /opt/regular [root@service99 ~]# cd /opt/regular [root@service99 regular]# pwd /opt/regular [root@service99 regular]# cp /etc/passwd temp_passwd</div>
纯文本
纯文本可以完全匹配对应的单词,需要注意的有正则表达式模式严格区分大小写。
//grep --color 主要是可以将匹配到的文本高亮显示,这样便于观察效果 [root@service99 regular]# grep --color "root" temp_passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin</div>
在正则表达式中,不必局限于完整的单词,所定义的文本出现在数据流的任意位置,正则表达式都将匹配。
[root@service99 regular]# ifconfig eth1 | grep --color "add" eth1 Link encap:Ethernet HWaddr 54:52:01:01:99:02 inet addr:192.168.2.99 Bcast:192.168.2.255 Mask:255.255.255.0 inet6 addr: fe80::5652:1ff:fe01:9902/64 Scope:Link</div>
当然也不必局限于单独的单词,也可以在文本字符串中出现空格和数字。
[root@service99 regular]# echo "This is line number 1" | grep --color "ber 1" This is line number 1</div>
特殊字符
在正则表达式模式中使用文本字符串时,有一个问题需要注意。
在正则表达式中定义文本字符串时有几个例外,正则表达式赋予了它们特殊的含义,如果在文本中使用这些特殊字符,有可能得不到预期的效果。
正则表达式认可的特殊字符:
.*[]^${}+?|()
</div>
如果想要使用这些特殊字符作为普通的文本字符,就需要转义(escape)它,即是在该字符前添加一个特殊字符,向正则表达式引擎说明:它应该将下一个字符解释为普通文本字符。
实现该功能的特殊字符是:“\”反斜杠字符
[root@service99 regular]# echo "This cat is $4.99" //双引号不会屏蔽特殊符号,所以系统会读取变量4.99的值,然而当前系统并没有该变量,就显示为空 This cat is .99 [root@service99 regular]# echo "This cat is \$4.99" //使用"\"转义$ This cat is $4.99 [root@service99 regular]# echo 'This cat is \$4.99' //单引号屏蔽元字符$ This cat is \$4.99 [root@service99 regular]# echo 'This cat is $4.99' This cat is $4.99 [root@service99 regular]# cat price.txt This price is $4.99 hello,world! $5.00 #$#$ This is "\". [root@service99 regular]# grep --color '\\' price.txt This is "\".</div>
定位符
从头开始
脱字符(^)尖角号定义从数据流中文本行开头开始的模式。
[root@service99 regular]# grep --color '^h' price.txt //以字母h开头的行 hello,world! [root@service99 regular]# grep --color '^$' price.txt //无输出结果,由于没有屏蔽特殊含义 [root@service99 regular]# grep --color '^\$' price.txt //以$符号开头的行 $5.00 [root@service99 regular]# echo "This is ^ test. " >> price.txt [root@service99 regular]# cat price.txt This price is $4.99 hello,world! $5.00 #$#$ This is "\". This is ^ test. [root@service99 regular]# grep --color '^' price.txt //直接使用会显示所有的内容 This price is $4.99 hello,world! $5.00 #$#$ This is "\". This is ^ test. [root@service99 regular]# grep --color '\^' price.txt //单独使用,并在最前面时需要屏蔽 This is ^ test. [root@service99 regular]# grep --color 'is ^' price.txt //符号不在最前面时,无需屏蔽,直接使用即可 This is ^ test.</div>
查找结尾
美元符号$特殊字符定义结尾定位,在文本模式之后添加这个特殊字符表示数据行必须以此文本模式结束。
[root@service99 regular]# grep --color '\.$' price.txt //“.”在正则表达式中也有特殊含义,请屏蔽,具体的请往下看 This is "\". [root@service99 regular]# grep --color '\. $' price.txt //由于我在输入的时候,多加了一个空格,所以各位需要慎重和小心 This is ^ test. //在正则表达式中,空格作为字符计。 [root@service99 regular]# grep --color '0$' price.txt $5.00 [root@service99 regular]# grep --color '9$' price.txt This price is $4.99</div>
联合定位
比较常用的就是“^$” 表示空行
结合“^#”,由于#在Linux代表注释
输出该文本的有效配置
[root@service99 regular]# cat -n /etc/vsftpd/vsftpd.conf | wc -l 121 [root@service99 regular]# grep -vE '^#|^$' /etc/vsftpd/vsftpd.conf //v表示反选,E表示支持扩展正则“|”是扩展正则的符号,往下看,后面有 anonymous_enable=YES local_enable=YES write_enable=YES local_umask=022 anon_upload_enable=YES anon_mkdir_write_enable=YES anon_other_write_enable=YES anon_umask=022 dirmessage_enable=YES xferlog_enable=YES connect_from_port_20=YES xferlog_std_format=YES listen=YES pam_service_name=vsftpd userlist_enable=YES tcp_wrappers=YES</div>
字符出现范围
{n,m} //前一个字符出现了n到m次
{n,} //前一个字符出现了n次以上
{n} //前一个字符出现了n次
[root@service99 regular]# grep --color "12345\{0,1\}" price.txt 1234556 [root@service99 regular]# grep --color "12345\{0,2\}" price.txt 1234556</div>
点字符
点特殊字符用于匹配除换行符之外的任意单个字符,但点字符必须匹配一个字符;如果在圆点位置没有字符,那么模式匹配失败。
[root@service99 regular]# grep --color ".s" price.txt This price is $4.99 This is "\". This is ^ test. [root@service99 regular]# grep --color ".or" price.txt hello,world!</div>
字符类
字符类可以定义一类字符来匹配文本模式中的某一位置。如果在字符类中的某一字符在数据流中,就和模式匹配。
为定义字符类,需要使用方括号。应该将要包括在该类中的所有字符用方括号括起来,然后模式中使用整个字符类,就像任意的其他通配符一样。
[root@service99 regular]# grep --color "[abcdsxyz]" price.txt This price is $4.99 hello,world! This is "\". This is ^ test. [root@service99 regular]# grep --color "[sxyz]" price.txt This price is $4.99 This is "\". This is ^ test. [root@service99 regular]# grep --color "[abcd]" price.txt This price is $4.99 hello,world! [root@service99 regular]# grep --color "Th[ais]" price.txt //Th 后的第一个字符在【ais】中匹配的 This price is $4.99 This is "\". This is ^ test. [root@service99 regular]# grep -i --color "th[ais]" price.txt //-i 表示不区分大小写 This price is $4.99 This is "\". This is ^ test.</div>
如果不能确定某个字符的大小写,就可以使用该模式: