Shell工具中正则表达式技术
awk, sed和egrep是Unix中文本处理相关的Shell工具。awk采用了DFA匹配引擎。egrep依据说使用的功能在DFA和NFA引擎之间进行切换(实现了两中引擎)。sed采用传统的NFA匹配引擎。如果想进一步了解传统的NFA引擎背后的规则,请看“正则表达式和模式匹配”一节。
本章涵盖GNU egrep 2.4.2,一个文本行搜索程序;GNU sed 3.2,一个脚本编辑命令工具;和GNU awk 3.1,一种文本处理语言。
支持的元字符
awk, sed和egrep支持表61到表65中列出来的元字符和元序列。关于每一个元字符的详述,请看“正则表达式元字符、模式和结构”一节。
Shell字符表示 |
||
序列名 |
序列描述 |
支持工具 |
/a |
告警(bell) |
awk, sed |
/b |
空格,只有在字符类中有效 |
awk, |
/f |
分页 |
awk, sed |
/n |
换行 |
awk, sed |
/r |
回车 |
awk, sed |
/t |
水平制表符 |
awk, sed |
/v |
垂直制表符 |
awk, sed |
/ooctal |
通过1、2或3个八进制码数指定的字符 |
sed |
/octal |
通过1、2或3个八进制码数指定的字符 |
awk |
/xhex |
通过1个或2个十六进制数指定的字符 |
awk, sed |
/x{hex} |
通过十六进制码指定的字符 |
awk, sed |
/ddecimal |
通过1个或2个十进制数指定的字符 |
awk, sed |
/cchar |
命名的控制字符 |
sed |
/b |
空格 |
awk |
/matecharacter |
转义元字符,所以它仅表示自身 |
awk, sed, egrep |
表61 Shell字符表示
Shell字符类和类似(class-like)结构 |
||
字符类 |
类描述 |
支持工具 |
[…] |
列出来的或包含在列表范围的单一字符 |
awk, sed, egrep |
[^…] |
不在列出来的或不包含在列表范围的单一字符 |
awk, sed, egrep |
. |
除换行之外的任意字符 |
awk, sed, egrep |
/w |
字字符,[a-zA-Z0-9_] |
egrep, sed |
/W |
非字字符, [^a-zA-Z0-9_] |
egrep, sed |
[:prop:] |
匹配POSIX字符集内的任意字符 |
awk, sed |
[^[:prop:]] |
匹配不在POSIX字符集内的任意字符 |
awk, sed |
表62 Shell字符类和类似(class-like)结构
Shell锚和其他0宽测试 |
||
序列名 |
序列描述 |
支持工具 |
^ |
匹配字符串的开头,即时有内切的换行 |
awk, sed, egrep |
$ |
匹配字符串末尾,即时有内切的换行 |
awk, sed, egrep |
/< |
匹配字边界的起始位置 |
egrep |
/> |
匹配字边界的末尾 |
egrep |
表63 Shell锚和其他0宽测试
Shell注释和模式转换器 |
||
模式名 |
模式描述 |
支持工具 |
flag:i或I |
ASCII字符大小写不敏感匹配 |
sed |
命令行选项:-i |
ASCII字符大小写不敏感匹配 |
egrep |
set IGNORECASE为非0(none-zero) |
Unicode字符大小写不敏感匹配 |
awk |
表64 hell注释和模式转换器
Shell归组、捕获、条件和控制 |
||
序列 |
序列描述 |
支持工具 |
(PATTERN) |
归组 |
awk |
(PATTERN/) |
组和捕获字匹配,填写/1,/2,...,/9 |
sed |
/n |
包含第n个被捕获子匹配 |
sed |
...|... |
替换;匹配一个或其他 |
awk, sed, egrep |
贪婪计量器 |
||
* |
匹配0或多次 |
awk, sed, egrep |
+ |
匹配1次或多次 |
awk, sed, egrep |
? |
匹配1次或0次 |
awk, sed, egrep |
/{n/} |
匹配精确的n次 |
sed, egrep |
/{n,/} |
至少匹配n次 |
sed, egrep |
/{x,y/} |
至少匹配x次,最多y次 |
sed, egrep |
表65 Shell归组、捕获、条件和控制
egrep
grep [options] pattern files
grep在文件搜索pattern发生的位置,并打印出每一个匹配的行。
实例
grep实例 |
$ echo 'Spiderman Menaces City!' > dailybugle.txt $ egrep -i 'spider[- ]?man' dailybugle.txt Spiderman Menaces City! |
sed
sed '[address1][,address2]s/pattern/replacement/[flags]' files
sed -f script files
默认的情况下sed把替换应用于files中的每一行。每一个address既可以是一个行号,也可以是一个正则表达式。当在正则表达式中使用时,必须在双方斜杆之内定义(/.../)。
如果指定了address1,那么替换从指定的行开始,或者第一个匹配的行,到文件末尾为止,或由address2指定或匹配的行。&和/n将在replacement中作为匹配结果被解释。
&被pattern匹配的文本替换。/n与当前匹配中捕获组(1...9)有关。以下是可用的标识:
n 替换一行内第n个匹配,n在1到512之间。
g 替换一行中所发生的所有pattern。
p 打印所有成功替换的行。
w file 把成功的替换写到文件中。
实例
把时间格式从MM/DD/YYYY 改为DD.MM.YYYY |
$ echo 12/30/1969' | sed 's!/([0-9][0-9]/)//([0-9][0-9]/)//([0-9]/{2,4/}/)! /2./1./3!g' |
awk
awk 'instruction' files
awk –f script files
包含在instruction或 script中脚本必须由一系列的/pattern/ {action}对组成。action码应用于被pattern的每一行。awk还为模式匹配提供了一些函数。
函数
match(text, pattern)
如果pattern匹配text,返回text中匹配的起始位置。一个成功的匹配还设置变量RSTART的值为匹配起始位置,设置变量RLENGTH的值为匹配中字符的个数。
gsub(pattern, replacement, text)
用replacement来替换text中每一个pattern匹配,并返回替换的次数。如果没有指定text则默认为$0。
sub(pattern, replacement, text)
用replacement来替换text中第一个pattern匹配,并返回替换的次数。一个成功的替换返回1,一个不成功的替换返回0。如果没有指定text则默认为$0。
实例
创建一个awk文件,并通过命令行执行这个文件 |
$ cat sub.awk { gsub(/https?:////[a-z_.//w////#~:?+=&;%@!-]*/, "<a href=/"/&/">/&</a>"); } $ echo "Check the web site, http://www.oreilly.com/ catalog/repr" | awk -f sub.awk |