awk Oneliner(四)字符串和数组
awk oneliner一共分为五部分(该部分为作者在前四部分发表后的一年以后做的一个总结),而国内的译文大多也只到第四部分。我也到作者的博客上去看过所有的原文,显然如果前四部分都完全掌握了,第五部分看起来只是一个小case。
1、创建一个固定长度的字符串
1awk 'BEGIN { while (a++<513) s=s "x"; print s }'
这个段程序用BEGIN这个特殊的匹配模式让后面的代码在awk试图读入任何东西前就执行。在里面是一个被执行了513次的循环,每次循环中“x”都被添加到变量s的最后。循环结束后,s的内容被输出。因为这段代码只有这一句,所以awk在执行完BEGIN模式语句后就退出了。这段循环代码不仅仅可用在BEGIN中,你可以在awk的任何代码段里面使用,包括END。
很不幸这段代码不是最有效率的,这是一个线性的解决方案。Awk Tips, Tricks and Pitfalls的作者 waldner 有一个非线性的解决方案:
1function rep(str, num, remain, result) {
2 if (num < 2) {
3 remain = (num == 1)
4 } else {
5 remain = (num % 2 == 1)
6 result = rep(str, (num - remain) / 2)
7 }
8 return result result (remain ? str : "")
9}
该函数同样用到三元运算a?b:c,而定义的该函数的内部又不停的调用函数本身,达到循环的目的。而前面的if……else语句主要用业说明remain是一个奇数。而通过下面的语句调用该函数:
1awk 'BEGIN { s = rep("x", 513) }'
以达到上面那段不高效的但确十分简洁的语句一样的效果。
2、在某个位置插入指定长度的字符串
1gawk --re-interval 'BEGIN{ while(a++<49) s=s "x" }; { sub(/^.{6}/,"&" s) }; 1'
这段代码只能在gawk下使用,因为它用到了interval expression,即这里的{6},作用是让前一个字符.匹配多次。.{6}便可以匹配6个任意字符。gawk使用interval expression需要用到参数-re-interval。
同前一例一样,首先在BEGIN段里面,建立了一个49个字符长的字符串放在变量s里。接下来是对每一行,进行替换,&这里代表的是匹配的字符串部分,所以sub的结果是将每一行第7个字符开始的内容替换成了s。然后是逐行输出。如果不是gawk,需要这样写
1awk 'BEGIN{ while(a++<49) s=s "x" }; { sub(/^....../,"&" s) }; 1'
其输出结果为从每行的第六个字符开始,连续输出49个x,然后再接着输出原来的行第七个字符及其以后的内容。如果每行不足七个字符时,该行输出的值不变。
注意:上面语句中的点并不是点本身的意思,而是代码任意一个字符,有点类似于bash脚本中用到字段?所代表的意思。
3、利用字符串建立数组
1split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", month, " ")
其初,我一直不能白作者为什么写上面的例子,而显然在bash shell中split也没有这个用法。而在php的split语句中我倒是常见到该函数的使用上面的有法。显然作者意思已经很明了,该例中作者创建了一个array,其中month[1]=Jan、month[2]=Feb,后面依次类推。(而后面将会讲到awk也具有类似的用法。)
建立用字符串做编号的数组(类似Ruby的Hash,Python的dict)
1for (i=1; i<=12; i++) mdigit[month[i]] = i
不多做解释,只是用来类比。显然bash中不会存在这样的用法。输出第5个字段为abc123的行
1awk '$5 == "abc123"'
2等价于awk '$5 == "abc123" {print $0}'
输出第5个字段不为abc123的行
1awk '$5 != "abc123"'
2等价于awk '$5 != "abc123" {print $0}'
3或awk '!($5 == "abc123")'
输出第7字段匹配某个正则表达式的行
1awk '$7 ~ /^[a-f]/'
这里用了~来进行正则表达式的匹配哦。如果你要不匹配的行,可以
1awk '$7 !~ /^[a-f]/'
捐赠本站(Donate)
如您感觉文章有用,可扫码捐赠本站!(If the article useful, you can scan the QR code to donate))
- Author: shisekong
- Link: https://blog.361way.com/awk-oneliner-four/1684.html
- License: This work is under a 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. Kindly fulfill the requirements of the aforementioned License when adapting or creating a derivative of this work.