awk中pattern、action和{}的解释

24 篇文章 0 订阅

转自:http://blog.chinaunix.net/uid-20006382-id-1987689.html
M.Tansley 05/99 48311 Green 8 40 44 
J.Lulu 06/99 48317 green 9 24 26 
P.Bunny 02/99 48 Yellow 12 35 28 
J.Troll 07/99 4842 Brown-3 12 26 26 

第一种写法: 
awk 'gsub(/4842/,4841);{print $0}' grade.txt 
结果如下:有两行的被替代行输出(有一个分号) 
M.Tansley 05/99 48311 Green 8 40 44 
J.Lulu 06/99 48317 green 9 24 26 
P.Bunny 02/99 48 Yellow 12 35 28 
J.Troll 07/99 4841 Brown-3 12 26 26 
J.Troll 07/99 4841 Brown-3 12 26 26

第二种写法:与第一种的区别在于将{写到了单引号后边。 
awk '{gsub(/4842/,4841);print $0}' grade.txt 
结果如下:仅显示出一行的被替代结果,其它全显示。 
M.Tansley 05/99 48311 Green 8 40 44 
J.Lulu 06/99 48317 green 9 24 26 
P.Bunny 02/99 48 Yellow 12 35 28 
J.Troll 07/99 4841 Brown-3 12 26 26

第三种写法:与第一种区别是没有了中间的分号,与第二种的区别是没有了分号但{放到了中间。 
awk 'gsub(/4842/,4841) {print $0}' grade.txt 
结果如下: 
J.Troll 07/99 4841 Brown-3 12 26 26 
不知道为什么会出现这种情况,分号在其中的含义是什么?{}的作用到底体现了什么?为什么动了一个{,就会出现第一、二两种不同的结果?

我想man awk是最好的老师了,看其中一段: 

代码:

      AWK is a line-oriented language.  The pattern comes first, and then the 
      action.  Action statements are enclosed in { and }.  Either the pattern 
      may be missing, or the action may be missing, but, of course, not both. 
      If the pattern is missing, the action  is  executed  for  every  single 
      record of input.  A missing action is equivalent to 
             { print } 





从你的第3个写法说起: 
awk 'gsub(/4842/,4841) {print $0}' 
这是个标准的/pattern/{action}写法 
等于 if(gsub(..)){ 
         print $0 
       } 
因为gsub()返回值是成功替换了字符串几次,只有匹配替换成功才会返回不为0(你的例子匹配了一次,所有返回1,即为true,因此要执行print语句。所有只有在匹配行才会执行“print $0”语句,所有就出现你说的显示一行。 

注意这里你可以直接写成 

awk 'gsub(/4842/,4841)' 

因为后面没写,awk会默认action为print $0 


但如果在两边加上{},即 

awk '{gsub(/4842/,4841)}' 

就与不加不同了,变成了 
//{action}的形式。此时pattern省掉,即对每一行进行处理,执行后面的action。 

gsub()变成了action,只是对$0按条件替换,替换结束一行就处理完了进入下一行处理,也就不会将此行内容打印出来了。 

这里就不会出现默认action的情况了,因为它本身是action嘛。 

action可以有多个语句,每个语句间用分号隔开,注意每个语句都是一个/pattern/{action}。 

弄清楚这些,再看你的第一二种写法就很好理解了。 


第2种) 

awk '{gsub(/4842/,4841);print $0}' grade.txt 

这是我们看作 
//{//{gsub(..)};//{print $0} 

因此对每一行执行一次gsub,一次print,所有结果是和无论是否gsub成功,都会显示原文件的一行,有“4842”字符串的行显示成替换后的行。 


最后看第一种写法: 
awk 'gsub(/4842/,4841);{print $0}' grade.txt 

看成 /gsub()/{print};//{print $0} 

看到了吗,这种写法和第三种只有一个分号的区别,可意义完全不一样了:) 

注意到了吗,如果替换成功会打印一次,然后又执行一次后面的{print $0}语句,这样的结果就会是不匹配行打印一次,而匹配行会连续打印两行。 


正常情况下我们都希望对每一行进行处理,所有正常情况下都会写成 

awk  '{ .............}' 

的形式。 

我想你看了上面这些就能够明白为什么我们习惯于这种写法的原因了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值