正则表达式
正则表达式是你所定义的模式模板(pattern template),Linux工具可以用它来过滤文本。Linux工具(比如sed编辑器或gawk程序)能够在处理数据时使用正则表达式对数据进行模式匹配。如果数据匹配模式,它就会被接受并进一步处理;如果数据不匹配模式,它就会被滤掉。正则表达式是通过正则表达式引擎(regular expression engine)实现的。正则表达式引擎是一套底层软件,负责解释正则表达式模式并使用这些模式进行文本匹配
两种引擎
POSIX基础正则表达式(basic regular expression,BRE)引擎
POSIX扩展正则表达式(extended regular expression,ERE)引擎
sed 只符合BRE 规范,出于速度的考虑
gawk 用ERE 引擎
一、定义BRE 模式
文本空格和正则表达式空格没有区别
[root@localhost gawk]# echo "the test txt 1" |sed -n '/ 1/p' the test txt 1 [root@localhost gawk]#
特殊字符串
.*[]^${}\+?|()
#再找这些字符串时需要进行过滤
[root@localhost gawk]# echo "$ 3 the" |sed -n '/\$/p' $ 3 the [root@localhost gawk]#
锚字符
脱字符(^)定义从数据流中文本行的行首开始的模式。如果模式出现在行首之外的位置,正则表达式模式则无法匹配
跟在行首查找模式相反的就是在行尾查找。特殊字符美元符($)定义了行尾锚点。将这个特殊字符放在文本模式之后来指明数据行必须以该文本模式结尾。
组合锚定
[root@localhost gawk]# cat data1 test text the cost is $4.0 [root@localhost gawk]# sed -n '/^test text$/p' data1 test text [root@localhost gawk]#
点号字符
特殊字符点号用来匹配除换行符之外的任意单个字符。
[root@localhost gawk]# cat data1 test text the cost is $4.0 the cost isis $4.0 is cost $4.0 [root@localhost gawk]# sed -n '/.is/p' data1 #正则表达式中空格也是字符 the cost is $4.0 the cost isis $4.0 [root@localhost gawk]#
字符组
[root@localhost gawk]# cat data1 test text the cost is $4.0 the cost isis $4.0 is cost $4.0 the is cast $4.0 the is cbst $4.0 [root@localhost gawk]# sed -n '/[ab]st/p' data1 the is cast $4.0 the is cbst $4.0 [root@localhost gawk]#
排除型字符组
反转字符组,寻找组中没有的字符,空格也是字符
[root@localhost gawk]# cat data1 test text the cost is $4.0 the cost isis $4.0 is cost $4.0 the is cast $4.0 the is cbst $4.0 [root@localhost gawk]# sed -n '/[^ab]is/p' data1 the cost is $4.0 the cost isis $4.0 the is cast $4.0 the is cbst $4.0 [root@localhost gawk]#
区间
[root@localhost gawk]# echo "28392" | sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p' 28392 [root@localhost gawk]# echo "a8392" | sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p' [root@localhost gawk]# echo "448392" | sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p' [root@localhost gawk]#
[root@localhost gawk]# echo "I'm getting too fat" |sed -n '/[a-ch-m]at/p' [root@localhost gawk]# echo "I'm getting too lat" |sed -n '/[a-ch-m]at/p' I'm getting too lat [root@localhost gawk]#
BRE特殊字符组
BRE特殊字符组 [[:alpha:]] 匹配任意字母字符,不管是大写还是小写 [[:alnum:]] 匹配任意字母数字字符0~9、A~Z或a~z [[:blank:]] 匹配空格或制表符 [[:digit:]] 匹配0~9之间的数字 [[:lower:]] 匹配小写字母字符a~z [[:print:]] 匹配任意可打印字符 [[:punct:]] 匹配标点符号 [[:space:]] 匹配任意空白字符:空格、制表符、NL、FF、VT和CR [[:upper:]] 匹配任意大写字母字符A~Z
[root@localhost gawk]# sed -n '/^[[:digit:]]/p' data1 123 test [root@localhost gawk]# cat data1 test text 123 test the cost is $4.0 the cost isis $4.0 is cost $4.0 the is cast $4.0 the is cbst $4.0 [root@localhost gawk]# sed -n '/^[[:digit:]]/p' data1 123 test [root@localhost gawk]#
星号
在字符后面放置星号表明该字符必须在匹配模式的文本中出现0次或多次。
[root@localhost gawk]# echo "ik" |sed -n '/iee*k/p' #e 出现0次或者多次 [root@localhost gawk]# echo "ik" |sed -n '/ie*k/p' ik [root@localhost gawk]#
root@localhost gawk]# echo "test txt peoplea." |sed -n '/people.*/p' test txt peoplea. [root@localhost gawk]# echo "test txt peopleadf." |sed -n '/people.*/p' test txt peopleadf. [root@localhost gawk]# echo "test txt people1." |sed -n '/people.*/p' test txt people1. [root@localhost gawk]#
[root@localhost gawk]# echo "ffffsassee" |sed -n '/f[ds]*a/p' #d 或者s 出现 0次或者多次 ffffsassee
二、扩展正则表达式(ERE)
POSIX ERE模式包括了一些可供Linux应用和工具使用的额外符号。gawk程序能够识别ERE模式,但sed编辑器不能
问号
问号类似于星号,不过有点细微的不同。问号表明前面的字符可以出现0次或1次,但只限于此。它不会匹配多次出现的字符。
[root@localhost gawk]# echo "bt" |gawk '/be?t/{print $0}' bt [root@localhost gawk]# echo "bet" |gawk '/be?t/{print $0}' bet [root@localhost gawk]# echo "beet" |gawk '/be?t/{print $0}' [root@localhost gawk]#
加号
加号是类似于星号的另一个模式符号,但跟问号也有不同。加号表明前面的字符可以出现1次或多次,但必须至少出现1次。如果该字符没有出现,那么模式就不会匹配。
[root@localhost gawk]# echo "bt" |gawk '/be+t/{print $0}' [root@localhost gawk]# echo "bet" |gawk '/be+t/{print $0}' bet [root@localhost gawk]# echo "beet" |gawk '/be+t/{print $0}' beet [root@localhost gawk]# echo "beeet" |gawk '/be+t/{print $0}' beeet [root@localhost gawk]#
使用花括号
ERE中的花括号允许你为可重复的正则表达式指定一个上限。这通常称为间隔(interval)。可以用两种格式来指定区间,默认情况下,gawk程序不会识别正则表达式间隔。必须指定gawk程序的--re- interval命令行选项才能识别正则表达式间隔。
m:正则表达式准确出现m次。
m, n:正则表达式至少出现m次,至多n次。
这个特性可以精确调整字符或字符集在模式中具体出现的次数。
[root@localhost gawk]# echo "bt" | gawk --re-interval '/be{1}t/{print $0}' [root@localhost gawk]# echo "bet" | gawk --re-interval '/be{1}t/{print $0}' bet [root@localhost gawk]# echo "beet" | gawk --re-interval '/be{1}t/{print $0}' [root@localhost gawk]#
[root@localhost gawk]# echo "beet" | gawk --re-interval '/be{1,2}t/{print $0}' #m 至少出现m 次,至多出现n 次 beet [root@localhost gawk]# echo "bt" | gawk --re-interval '/be{1,2}t/{print $0}' [root@localhost gawk]# echo "beeet" | gawk --re-interval '/be{1,2}t/{print $0}' [root@localhost gawk]#
管道符号
管道符号允许你在检查数据流时,用逻辑OR方式指定正则表达式引擎要用的两个或多个模式。如果任何一个模式匹配了数据流文本,文本就通过测试。如果没有模式匹配,则数据流文本匹配失败
使用管道符号的格式如下:
expr1|expr2|...
[root@localhost gawk]# echo "The cat is asleep" |gawk '/cat|dog/{print $0}' The cat is asleep [root@localhost gawk]# echo "The dog is asleep" |gawk '/cat|dog/{print $0}' The dog is asleep [root@localhost gawk]#
表达式分组
正则表达式模式也可以用圆括号进行分组。当你将正则表达式模式分组时,该组会被视为一个标准字符。可以像对普通字符一样给该组使用特殊字符。
[root@localhost gawk]# echo "testqaz" |gawk '/test(qaz)?/{print $0}' testqaz [root@localhost gawk]# echo "testqad" |gawk '/test(qaz)?/{print $0}' testqad [root@localhost gawk]# echo "testqad" |gawk '/test(qaz)+/{print $0}' [root@localhost gawk]#
[root@localhost gawk]# echo "tab" |gawk '/(r|q)a(c|b)/{print $0}' [root@localhost gawk]# echo "tab" |gawk '/(t|q)a(c|b)/{print $0}' tab [root@localhost gawk]#
正则表达式实战
1.目录文件计数
#遍历环境变量目录并统计文件数量
#通过两个循环来处理数据
[root@localhost gawk]# cat countfiles.sh #!/bin/bash #count number of files in you path mypath=$(echo $PATH |sed 's/:/ /g') #对数据进行处理,将分隔符: 替换为空格,for 循环默认空格为分隔符 count=0 #设置初始数值0 for directory in $mypath;do #for 循环遍历目录 check=$(ls $directory) #ls 列出目录文件,并赋值给变量 check for item in $check;do #for 循环遍历文件 count=$[ $count + 1 ] #累加count done echo "$directory file count - $count" #输出目录文件数量 count=0 #统计计0,进入下一个目录循环操作 done [root@localhost gawk]# ./countfiles.sh /usr/local/sbin file count - 0 /usr/local/bin file count - 2 /usr/sbin file count - 472 /usr/bin file count - 925 ls: 无法访问/root/bin: 没有那个文件或目录 /root/bin file count - 0 [root@localhost gawk]#
验证电话号码
[root@localhost gawk]# cat testphone #!/bin/bash #gawk --re-interval '/^\(?[2-9][0-9]{2}\)?(| |-|\.)[0-9]{3}( |-|\.)[0-9]{4}/{print $0}' gawk --re-interval '/^\(?[5-7][0-9]{2}\)?(| |-|\.)[0-9]{3}(|-|\.)[0-9]{5}/{print $0}' [root@localhost gawk]#
验证邮箱
[root@localhost gawk]# cat testmail #在这个正则表达式中匹配任意大小写字母,数字,中横线,下划线,点号,出现至少一次或者多次 #!/bin/bash gawk --re-interval '/^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/{print $0}' [root@localhost gawk]# echo "12_3+@com.cn" |./testmail 12_3+@com.cn [root@localhost gawk]# echo "123@com.cn." |./testmail [root@localhost gawk]# echo "123+@com.cn" |./testmail 123+@com.cn
[root@localhost gawk]# echo "123+.qaz@com.cn" |./testmail
123+.qaz@com.cn
[root@localhost gawk]#