通用线程:Awk 实例( 七 )


myarr["1"]="Mr. Whipple"print myarr[1]
猜想这个代码片断的结果比较难 。awk 将 myarr["1"] 和 myarr[1] 看作数组的两个独立元素,还是它们是指同一个元素?答案是它们指的是同一个元素,awk 将打印 "Mr. Whipple",如同第一个代码片断一样 。虽然看上去可能有点怪,但 awk 在幕后却一直使用数组的字符串下标!
了解了这个奇怪的真相之后,我们中的一些人可能想要执行类似于以下的古怪代码:
myarr["name"]="Mr. Whipple"print myarr["name"]
这段代码不仅不会产生错误,而且它的功能与前面的示例完全相同,也将打印 "Mr. Whipple"!可以看到,awk 并没有限制我们使用纯整数下标;如果我们愿意,可以使用字符串下标,而且不会产生任何问题 。只要我们使用非整数数组下标,如 myarr["name"],那么我们就在使用关联数组 。从技术上讲,如果我们使用字符串下标,awk 的后台操作并没有什么不同(因为即便使用“整数”下标,awk 还是会将它看作是字符串) 。但是,应该将它们称作关联数组 -- 它听起来很酷,而且会给您的上司留下印象 。字符串化下标是我们的小秘密 。;)
数组工具
谈到数组时,awk 给予我们许多灵活性 。可以使用字符串下标,而且不需要连续的数字序列下标(例如,可以定义 myarr[1] 和 myarr[1000],但不定义其它所有元素) 。虽然这些都很有用,但在某些情况下,会产生混淆 。幸好,awk 提供了一些实用功能有助于使数组变得更易于管理 。
首先,可以删除数组元素 。如果想要删除数组 fooarray 的元素 1,输入:
delete fooarray[1]
而且,如果想要查看是否存在某个特定数组元素,可以使用特殊的 "in" 布尔运算符,如下所示:
if ( 1 in fooarray ) { print "Ayep! It"s there."} else { print "Nope! Can"t find it."}
下一篇
本文中,我们已经讨论了许多基础知识 。下一篇中,我将演示如何使用 awk 的数学运算和字符串函数,以及如何创建您自己的函数,使您完全掌握 awk 知识 。我还将指导您创建支票簿结算程序 。那时,我会鼓励您编写自己的 awk 程序 。请查阅以下参考资料 。
在 awk 系列的这篇总结中,Daniel 向您介绍 awk 重要的字符串函数,以及演示了如何从头开始编写完整的支票簿结算程序 。在这个过程中,您将学习如何编写自己的函数,并使用 awk 的多维数组 。学完本文之后,您将掌握更多 awk 经验,可以让您创建功能更强大的脚本 。
第三部分
格式化输出
虽然大多数情况下 awk 的 print 语句可以完成任务,但有时我们还需要更多 。在那些情况下,awk 提供了两个我们熟知的老朋友 printf() 和 sprintf() 。是的,如同其它许多 awk 部件一样,这些函数等同于相应的 C 语言函数 。printf() 会将格式化字符串打印到 stdout,而 sprintf() 则返回可以赋值给变量的格式化字符串 。如果不熟悉 printf() 和 sprintf(),介绍 C 语言的文章可以让您迅速了解这两个基本打印函数 。在 Linux 系统上,可以输入 "man 3 printf" 来查看 printf() 帮助页面 。
以下是一些 awk sprintf() 和 printf() 的样本代码 。可以看到,它们几乎与 C 语言完全相同 。
x=1b="foo"printf("%s got a %d on the last testn","Jim",83)myout=("%s-%d",b,x)print myout
此代码将打印:
Jim got a 83 on the last testfoo-1
字符串函数
awk 有许多字符串函数,这是件好事 。在 awk 中,确实需要字符串函数,因为不能象在其它语言(如 C、C和 Python)中那样将字符串看作是字符数组 。例如,如果执行以下代码:
mystring="How are you doing today?"print mystring[3]
将会接收到一个错误,如下所示:
awk: string.gawk:59: fatal: attempt to use scalar as array
噢,好吧 。虽然不象 Python 的序列类型那样方便,但 awk 的字符串函数还是可以完成任务 。让我们来看一下 。

推荐阅读