Awk实例第2部分分析和总结.docx
文本预览下载声明
声明:
声明: 本文的原始版本最初发表于IBM developerWorks,现在所有权归属 Westtech Information Services。本文档是原始文档的更新版本, 包含了 Gentoo Linux 文档团队所做的很多改进。
现在无人积极维护本文档。
Awk 实例,第 2 部分
内容:
记录、循环和数组多行记录
awk 是一种用于读取和处理结构化数据(如系统的/etc/passwd 文件)的极佳工具。/etc/passwd 是 UNIX 用户数据库,并且是用冒号定界的文本文件,它包含许多重要信息,包括所有现有用户帐户和用户标识,以及其它信息。在我的前一篇文章中,我演示了 awk 如何轻松地分析这个文件。我们只须将 FS(字段分隔符)变量设置成:。
正确设置了 FS 变量之后,就可以将 awk 配置成分析几乎任何类型的结构化数据, 只要这些数据是每行一个记录。然而,如果要分析占据多行的记录,仅仅依靠设置 FS 是不够的。在这些情况下,我们还需要修改 RS 记录分隔符变量。RS 变量告诉 awk 当前记录什么时候结束,新记录什么时候开始。
譬如,让我们讨论一下如何完成处理“联邦证人保护计划”所涉及人员的地址列表的任务:
代码 1.1: “联邦证人保护计划”所涉及人员的地址列表
代码 1.1: “联邦证人保护计划”所涉及人员的地址列表
Jimmy the Weasel
100 Pleasant Drive
San Francisco, CA 12345
Big Tony
200 Incognito Ave.
Suburbia, WA 67890
理论上,我们希望 awk 将每 3 行看作是一个独立的记录,而不是三个独立的记录。如果 awk 将地址的第一行看作是第一个字段($1),街道地址看作是第二个字段($2),城市、州和邮政编码看作是第三个字段$3,那么这个代码就会变得很简单。以下就是我们想要得到的代码:
代码 1.2: 从地址新建一个字段
代码 1.2: 从地址新建一个字段
BEGIN {
FS=\n
FS=\n
RS=
}
在上面这段代码中,将FS 设置成\n告诉 awk 每个字段都占据一行。通过将RS 设置成,还会告诉 awk 每个地址记录都由空白行分隔。一旦 awk 知 道是如何格式化输入的,它就可以为我们执行所有分析工作,脚本的其余部分很简单。让我们研究一个完整的脚本,它将分析这个地址列表,并将每个记录打印在一 行上,用逗号分隔每个字段。
代码 1.3: 完整的脚本
代码 1.3: 完整的脚本
BEGIN {
FS=\n RS=
}
{ print $1 , $2 , $3 }
如果这个脚本保存为 address.awk,地址数据存储在文件 address.txt 中,可以通过输入awk -f address.awk address.txt来执行这个脚本。此代码将产生以下输出:
代码 1.4: 脚本输出
代码 1.4: 脚本输出
Jimmy the Weasel, 100 Pleasant Drive, San Francisco, CA 12345 Big Tony, 200 Incognito Ave., Suburbia, WA 67890
OFS 和 ORS
在 address.awk 的 print 语句中,可以看到 awk 会连接(合并)一行中彼此相邻的字符串。我们使用此功能在同一行上的三个字段之间插入一个逗 号和空格(, )。这个方法虽然有用,但比较难看。与其在字段间插入,字符串,倒不如让通过设置一个特殊 awk 变量 OFS,让 awk 完成这件事。请参考下面这个代 码片断。
代码 1.5: 示例代码片断
代码 1.5: 示例代码片断
print Hello, there, Jim!
这行代码中的逗号并不是实际文字字符串的一部分。事实上,它们告诉 awk, Hello、there和Jim!是单独的字段,并且应该在每个字符串之间打印 OFS 变量。缺省情况下,awk 产生以下输出:
代码 1.6: awk 产生的输出
代码 1.6: awk 产生的输出
Hello there Jim!
这是缺省情况下的输出结果,OFS 被设置成 ,单个空格。不过,我们可以方便地重新定义 OFS,这样 awk 将插入我们中意的字段分隔符。以下是原始address.awk 程序的修订版,它使用 OFS 来输出那些中间的, 字符串:
代码
代码 1.7: 重新定义 OFS BEGIN {
FS=\n RS= OFS=,
}
{ print $1, $2, $3 }
awk 还有一个特殊变量 ORS,全称是“输出记录分隔符”。通过设置缺省为换行(\n) 的 OFS,我们可以控制在 print 语句结尾自
显示全部