2012-03-26
The “dollar” in awk
首先贴一个简单的awk命令,猜一下,这个命令执行之后的输出会是什么?
$ echo "" | awk '{OFS=","; $x = 1; $y = 1; $y = $x; $y += 1; print $x, $y;}'
理想中,输出应该是这个样子的:
1,2
但现实中,却是这个样子的:
2,2
这是怎么回事?难道awk的赋值不是值传递(assignment by value),而是引用传递(assigned by reference)?困惑了好久,先RTFM后STFW两招杀手锏下来也毫无结果,人家压根就没提awk还有值传递和引用传递的区别 T_T
盯着这个表达式看了好久,忽然恍然大悟,awk和php还有bash是不一样的,变量前面不需要加”$”引用,把”$”去掉后,一切正常:
$ echo "" | awk '{OFS=","; x = 1; y = 1; y = x; y += 1; print x, y;}' 1,2
那,加上”$”之后原本的变量的意义又变成什么了呢?为什么有这样看起来像引用传递的结果?
原来在awk中,”$”表示对字段(Field)的引用,诸如$0表示整条记录(Record),$1表示记录中的第一个字段,$2表示第二个,以此类推下去。当然,awk允许非常量类型的字段引用。$n也是可以的,如果n=1,则$n == $1
至此,再来看本文第一个例子,其实可以翻译如下:
$ echo "" | awk '{OFS=","; $0 = 1; $0 = 1; $0 = $0; $0 += 1; print $0, $0;}' 2,2
在脚本执行期间,x与y的值一直都是未初始化的0,因此,对于$x, $y的操作都是对$0的操作,所以看起来就像是引用一样。
终于搞明白了,可以松口气了,但是花费了近两个小时的时间。
吐槽这些语言语法混杂容易搞混之余,也只能怪自己学艺不精犯下此等低级错误 =。= 记录在此,以敬效尤