为了充分发挥shell编程的威力,你需要精通正则表达式。 在脚本编程中的一些命令和软件包普遍使用正则表达式,例如grep,expr,sed和awk.
19.1. 一个简要的正则表达式介绍
一个正式表达式是一个字符串.字符串里的字符被称为元字符,它们可以表示了比它们字面上看起来的意思更丰富的含义。例如,一个引用符号可以表示引用一个人演讲中的话,或者表示下面将要讲到的引申表示的意思。正则表达式是一个字符或/和元字符组合成的字符集,它们匹配(或指定)一个模式。.
一个正则表达式包含下面一个或多个项:
一个字符集. 这里的字符集里的字符表示的就是它们字面上的意思.正则表达式最简单的情况就是仅仅由字符集组成,而没有其他的元字符.
锚. 一个锚指明了正则表达式在一行文本中要匹配的位置,例如^和$就是锚.
修饰符. 它们用于展开或缩小(即是修改了)正则表达式匹配文本行的范围.修饰符包括了星号,括号和反斜杠符号.
正则表达是的主要作用是用来文本搜索和字串操作。一个正则表达式匹配一个字符或是一串字符--完整的一串字符或是另外一个字符串的子串.
星号 -- * -- 匹配前一个字符的任意多次(包括零次)。 "1133*"匹配11 + 一个或更多的3 + 可能的其他字符: 113,1133,111312,等等.
点 -- . -- 匹配除了新行符之外的任意一个字符. [1] "13." 匹配13 + 至少一个任意字符(包括空格): 1133,11333,但不匹配 13 (因为少了附加的至少一个任意字符).
脱字符 -- ^ -- 匹配一行的开头,但依赖于上下文环境,可能在正则表达式中表示否定一个字符集的意思.
美元符 -- $ -- 在正则表达式中匹配行尾. "^$" 匹配空行.
方括号 -- [...] -- 在正则表达式中表示匹配括号中的一个字符. "[xyz]" 匹配字符x,y,或z. "[c-n]" 匹配从字符c到n之间的任意一个字符. "[B-Pk-y]" 匹配从B到P 或从k到y的任意一个字符. "[a-z0-9]" 匹配任意小写字母或数字. "[^b-d]" 匹配除了从b到d范围内所有的字符. 这是正则表达式中反转意思或取否的一个例子。(就好像在别的情形中!字符所扮演的角色). 多个方括号字符集组合使用可以匹配一般的单词和数字模式。"[Yy][Ee][Ss]" 匹配yes,Yes,YES,yEs,等等. "[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]" 匹配社会安全码(Social Security number).
反斜杠字符 -- -- 转义(escapes) 一个特殊的字符,使这个字符表示原来字面上的意思. "$"表示了原来的字面意思"$",而不是在正则表达式中表达的匹配行尾的意思.同样,""也被解释成了字面上的意思"".
转义(escape)"尖角号" -- &;...&; -- 用于表示单词的边界. 尖角号必须被转义,因为不这样做的话它们就表示单纯的字面意思而已. "&;the&;" 匹配单词"the",但不匹配"them","there","other",等等.
bash$cattextfile
Thisisline1,ofwhichthereisonlyoneinstance.
Thisistheonlyinstanceofline2.
Thisisline3,anotherline.
Thisisline4.
bash$grep'the'textfile
Thisisline1,anotherline.
bash$grep'&;the&;'textfile
Thisistheonlyinstanceofline2.
|
扩展的正则表达式. 增加了一些元字符到上面提到的基本的元字符集合里. 它们在egrep,awk,和Perl中使用.
问号 -- ? -- 匹配零或一个前面的字符. 它一般用于匹配单个字符.
加号 -- + -- 匹配一个或多个前面的字符.它的作用和*很相似,但唯一的区别是它不匹配零个字符的情况.
1#GNU版本的sed和awk可以使用"+",2#但它应该转义一下.
3
4echoa111b|sed-ne'/a1+b/p'
5echoa111b|grep'a1+b'
6echoa111b|gawk'/a1+b/'
7#上面三句都是等价的效果.
8
9#多谢,S.C. |
转义"大括号" -- { } -- 指示前面正则表达式匹配的次数. 要转义是因为不转义的话大括号只是表示他们字面上的意思。这个用法只是技巧上的而不是基本正则表达式的内容。 "[0-9]{5}" 精确匹配5个数字 (从 0 到 9的数字).

|
大括号不能在“经典”(不是POSIX兼容)的正则表达式版本的awk中使用. 然而,gawk 有一个选项--re-interval来允许使用大括号(不必转义).
bash$echo2222|gawk--re-interval'/2{3}/'
2222
|
Perl和一些egrep版本不要求转义大括号. |
圆括号 -- ( ) -- 括起一组正则表达式. 它和下面要讲的"|"操作符或在用expr进行子字符串提取(substring extraction)一起使用很有用。
竖线 -- | -- "或"正则操作符用于匹配一组可选的字符.
bash$egrep're(a|e)d'misc.txt
Peoplewhoreadseemtobebetterinformedthanthosewhodonot.
Theclarinetproducessoundbythevibrationofitsreed.
|

|
一些sed,ed,和ex的版本像GNU的软件版本一样支持上面描述的扩展正则表达式的版本。 |
POSIX字符类. [:class:] 这是另外一个可选的用于指定匹配字符范围的方法。
[:alnum:] 匹配字母和数字.等同于A-Za-z0-9.
[:alpha:] 匹配字母. 等同于A-Za-z.
[:blank:] 匹配一个空格或是一个制表符(tab).
[:cntrl:] 匹配控制字符.
[:digit:] 匹配(十进制)数字. 等同于0-9.
[:graph:] (可打印的图形字符). 匹配 ASCII 码值的33 - 126之间的字符. 这和下面提到的 [:print:]一样,但是不包括空格字符.
[:lower:] 匹配小写字母. 等同于a-z.
[:print:] (可打印字符). 匹配 ASCII码值 32 - 126之间的字符. 这和上面提到的一样[:graph:],但是增多一个空格字符。
[:space:] 匹配空白字符 (空格符和水平制表符).
[:upper:] 匹配大写字母. 等同于A-Z.
[:xdigit:] 匹配十六进制数字. 等同于0-9A-Fa-f.

|
POSIX字符类一般都要求用引号或是双方括号double brackets ([[ ]])引起来.
bash$grep[[:digit:]]test.file
abc=723
|
这些字符类在一个受限的范围内甚至可能用在能用在通配(globbing)中.
bash$ls-l?[[:digit:]][[:digit:]]?
-rw-rw-r--1bozobozo0Aug2114:47a33b
|
为了理解POSIX字符类在脚本中的使用,请参考例子 12-18 和 例子 12-19. |
Sed,和Perl在脚本中被用作过滤器,"过滤"或转换文件/IO流的时候以正则表达式作为参数。参考例子 A-12和例子 A-17 来理解这种用法.
在正则表达式这个复杂主题的标准参考是Friedl的Mastering Regular Expressions.由Dougherty和Robbins写的 Sed & Awk也给出了一个清晰的正则表达式论述. 查看参考书目 找到这个主题更多的信息.
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|