俗话说,百闻不如一见,百见不如一干。这里,我们从网上搜集了一些awk方面的小练习,从实战中体验awk带给我们的便捷。
1. /tmp目录下有几个文件,ls返回部分结果如下:
amp-content-display-portlet-1.0.1-20120829.081044-11.war amp-facebook-post-editor-1.0.1-20120829.084615-1.war amp-services-portlet-1.0.2-20120829.085733-3.war
要求把版本号及后面的数字都给屏蔽了(即其中粉红色部分),只匹配文件名。
分析:这其实是一个正则匹配的问题,很多工具都可以实现,这里给出一种解法:
ls | awk '/^amp/ { sub(/-[0-9].*-[0-9]*/, "") print }' $*
sub函数对指定的正则表达式进行替换,省略了第三个参数,即对每一行$0进行匹配。
2. 某数据库文件 dat 如下(包含名字,电话,过去三个月的捐款共5个字段,以“:”隔开)
Mike Harrington:[510] 548-1278:250:100:175 Christian Dobbins:[408] 538-2358:155:90:201 Susan Dalsass:[206] 654-6279:250:60:50 Archie McNichol:[206] 548-1348:250:100:175 Jody Savage:[206] 548-1278:15:188:150 Guy Quigley:[916] 343-6410:250:100:175 Dan Savage:[406] 298-7744:450:300:275 Nancy McNeil:[206] 548-1278:250:80:75 John Goldenrod:[916] 348-4278:250:100:175 Chet Main:[510] 548-5258:50:95:135 Tom Savage:[408] 926-3456:250:168:200 Elizabeth Stachelin:[916] 440-1763:175:75:300
要求:a.显示所有电话号码 b. 显示Dan的电话号码 c. 显示Susan的名字和电话号码 d. 显示所有以D开头的姓 e. 显示所有以一个C或E开头的名 f. 显示所有只有四个字符的名 g. 显示所有区号为916的人名 h. 显示Mike的总捐款 i. 显示姓,其后跟一个逗号和名 j. 显示Savage的全名和电话号码,Chet的捐款,所有头一个月捐款$250的人名
解答:
a. 这是awk最基本的用法,分割和打印
awk 'BEGIN{ FS=":" } {print $2}' dat
b. 使用简单的匹配
awk 'BEGIN{ FS=":" } $1~/Dan/ {print $2}' dat
c. 同上
awk 'BEGIN{ FS=":" } $1~/Susan/ {print $1, $2}' dat
d. 调用了两次awk
awk 'BEGIN{ FS=":" } $1~/ D/ {print $1}' dat |awk '{ print $2 }'
e. 也可用 C|E 匹配
awk '/[CE]/ {print $1}' dat
f. length函数的使用
awk 'length($1) == 4 {print $1}' dat
g. 注意转义
awk 'BEGIN{ FS=":" } $2~/\[916]/ {print $1}' dat
h. 算数运算,自动类型判断
awk 'BEGIN{ FS=":" } $1~/Mike/ {print $3 + $4 + $5}' dat
i. 外国人名和姓是反着的
awk 'BEGIN{ FS=":" } {print $1}' dat | awk '{ print $2 "," $1 }'
j. 多个规则的使用
awk 'BEGIN{ FS=":" } $1~/Savage/ { print $1,$2 } $1~/Chet/ { print $3 + $4 + $5 } $3==250 { print $1 } ' dat