终于要弄完了。。。 原文见 http://www.catonmat.net/blog/update-on-famous-awk-one-liners-explained
创建一个固定长度的字符串
awk 'BEGIN { while (a++<513) s=s "x"; print s }'
这个段程序用BEGIN
这个特殊的匹配模式让后面的代码在awk试图读入任何东西前就执行。在里面是一个被执行了513次的循环,每次循环中“x”都被添加到变量s
的最后。循环结束后,s的内容被输出。因为这段代码只有这一句,所以awk在执行完BEGIN模式语句后就退出了。
这段循环代码不仅仅可用在BEGIN中,你可以在awk的任何代码段里面使用,包括END。
很不幸这段代码不是最有效率的,这是一个线性的解决方案。10 Awk Tips, Tricks and Pitfalls的作者 waldner 有一个非线性的解决方案
function rep(str, num, remain, result) {
if (num < 2) {
remain = (num == 1)
} else {
remain = (num % 2 == 1)
result = rep(str, (num - remain) / 2)
}
return result result (remain ? str : "")
}
我看不懂,被这awk oneliner的作者蒙了,没成高手…T_T
这个函数可以这样用
awk 'BEGIN { s = rep("x", 513) }'
在某个位置插入指定长度的字符串
gawk --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段里面,一个叫做s的49个字符长的字符串被建立了。接下来是对每一行,进行替换,&
这里代表的是匹配的字符串部分,所以sub的结果是将每一行第7个字符开始的内容替换成了s。然后是逐行输出。
如果不是gawk,需要这样写
awk 'BEGIN{ while(a++<49) s=s "x" }; { sub(/^....../,"&" s) }; 1'
orz
利用字符串建立数组
这里数组这个翻译,其实并不能十分正确的表达Array的含义。鉴于大部分时候大家都是这么叫的,这里也用数组代表Array。
split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", month, " ")
很简单,数组month被初始化了。month[1]
的内容是Jan,month[2]
是Feb,….
建立用字符串做编号的数组(类似Ruby的Hash,Python的dict)
for (i=1; i<=12; i++) mdigit[month[i]] = i
很明了,所以不说了,用到了上面的month数组。
输出第5个字段为abc123的行
awk '$5 == "abc123"'
没什么好说的,等价于
awk '$5 == "abc123" {print $0}'
输出第5个字段不为abc123的行
awk '$5 != "abc123"'
也等价于
awk '$5 != "abc123" {print $0}'
或
awk '!($5 == "abc123")'
输出第7字段匹配某个正则表达式的行
awk '$7 ~ /^[a-f]/'
这里用了~
来进行正则表达式的匹配哦。如果你要不匹配的行,可以
awk '$7 !~ /^[a-f]/'