shell正则表达式
正则表达式识别的特殊字符包括:
. * [ ] ^ $ { } \ + ? | ( )
如果要用某个特殊字符为文本字符,则必须转义
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed -n '/\$/p' data1 the cost is $4.0
另外'/'虽然不是正则表达式的特殊字符,但是也需要转义
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# echo '/ 111' | sed -n '/\//p' / 111
锚字符
脱字符(^)定义从数据流中文本行的行首开始的模式
行尾锚点($)
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# df -h|sed -n '/^\/dev\/vda/p' /dev/vda1 99G 2.8G 92G 3% /
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# df -h|sed -n '/\/dev$/p' devtmpfs 1.9G 0 1.9G 0% /dev
组合锚点,可以过滤出空白行
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# cat data2 1111 222 333 444 [root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sed '/^$/d' data2 1111 222 333 444
排除型字符组,会打印除了‘ch’以外的字符
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# echo "this test is at line four" | sed -n '/[^ch]at/p' this test is at line four
特殊字符组
[[: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@iZbp11f8g5h7oozejqy6k6Z test5.9]# echo "abc123" | sed -n '/[[:digit:]]/p' abc123
可以用[[:digit:]]代替[0-9]
星号
在字符后面放置星号表明该字符必须在匹配模式的文本中出现0次或多次
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# echo 'ik' | sed -n '/ie*k/p' ik
扩展正则表达式
sed编辑器和gawk程序的正则表达式引擎之间是有区别的。gawk程序可以使用大多数扩展正则表达式模式符号,并且能提供一些额外额过滤功能,而这些功能都是
sed编辑器所不具备的。但正因为如此,gawk程序在处理数据流是通常才比较慢
问号
问号类似于星号,不过有点细微的不同,问号表明前面的字符可以出现0次或1次,但只限于此
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# echo 'iek' |gawk '/ie?k/{print $0}' iek [root@iZbp11f8g5h7oozejqy6k6Z test5.9]# echo 'ik' |gawk '/ie?k/{print $0}' ik
加号
加号表示前面的字符可以出现1次或者多次,至少出现1次
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# echo 'beet'|gawk '/be+t/{print $0}' beet
使用花括号
ERE中的花括号允许为可重复的正则表达式指定一个上限。这通常称为间隔,可以用两种格式来指定区间。
m:正则表达式准确出现m次
m,n:正则表达式至少出现m次,至多n次
默认情况下,gawk程序不会之别正则表达式间隔,必须指定gawk程序的--re-interval命令行选项才能识别正则表达式间隔
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# echo 'bet' | gawk '/be{1,2}t/{print $0}' bet
表达式分组
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# echo "Staurday" | gawk '/Sta(urday)?/{print $0}' Staurday
正则表达式实际应用
统计$PATH下文件数量
[root@iZbp11f8g5h7oozejqy6k6Z test5.9]# cat test1.sh #! /bin/bash mypath=$(echo $PATH|sed 's/:/ /g') count=1 for p in $mypath do if [ -d $p ] then f=$(ls $p) for item in $f do count=$[ $count + 1 ] done echo "$p - $count" else echo "$p not found" fi done [root@iZbp11f8g5h7oozejqy6k6Z test5.9]# sh test1.sh /usr/local/sbin - 1 /usr/local/bin - 1 /usr/sbin - 414 /usr/bin - 1321 /root/bin not found
匹配电话号码
以杭州为例:
0571 1234 5678
[root@iZbp11f8g5h7oozejqy6k6Z ~]# echo "(0571-1234.5678"|gawk '/^\(?(0571)\)?(| |-|\.)[0-9]{4}( |-|\.)[0-9]{4}$/p' (0571-1234.5678 [root@iZbp11f8g5h7oozejqy6k6Z ~]# echo "(0571-1234.5678"|gawk '/^\(?(0571)\)?(| |-|\.)[0-9]{4}( |-|\.)[0-9]{4}$/{print $0}' (0571-1234.5678
其中
^\(? 表示开头为'('或者无(
(0571)为一个组
\)?表示有无 ')'
(| |-|\.)表示空格或者'-'或者'.'
[0-9]{4}表示出现4次数字
[0-9]{4}$表示以4个数字结尾
可以用来过滤号码
解析邮箱
username@hostname
username可以是数字字母以及 . - + _
hostname由一个或多个域名和一个服务器名组成只允许数字字母以及 . _
服务器名和域名都用.分隔,先指定服务器名,紧接着指定子域名
[root@iZbp11f8g5h7oozejqy6k6Z ~]# echo "w.-+gcy123@16ds3.com123"|gawk '/^([A-Za-z0-9_\.\+\-]+)@([a-zA-Z0-9_\.]+)\.([a-zA-Z0-9_\.]+)$/p' w.-+gcy123@16ds3.com123