Awk 入门/Nawk
外观
< Awk 入门
Awk 的最初版本是在 1977 年开发的。它针对快速编写“单行程序”或简短、快速、简陋的程序进行了优化。然而,一些用户非常喜欢 Awk,以至于他们将它用于更复杂的任务。引用语言作者的话:“当我们遇到一个不适合在一页上显示的程序时,我们感到震惊和惊讶。”一些用户将 Awk 视为他们主要编程工具,事实上许多人学习编程就是使用 Awk。
在作者克服了最初的震惊后,他们决定接受这一事实,并增强 Awk,使其成为更好的通用编程工具。新版本的 Awk 于 1985 年发布。新版本通常(如果不总是)被称为 Nawk(“新 Awk”),以区别于旧版本。
- Nawk 包含了一些重大改进。最重要的改进是用户可以定义自己的函数。例如,以下 Nawk 程序实现了“signum”函数
{for (field=1; field<=NF; ++field) {print signum($field)}}; function signum(n) { if (n<0) return -1 else if (n==0) return 0 else return 1}
函数声明可以放置在程序中的任何地方,只要匹配-操作子句可以放置的地方都可以。所有参数都是函数的局部变量。局部变量可以在函数内部定义。
- 第二个改进是一个新函数“getline”,它允许从除了在调用时指定的命令行中的文件以外的文件中输入(以及从管道输入)。“Getline”可以以多种方式使用
getline Loads $0 from current input. getline myvar Loads "myvar" from current input. getline myfile Loads $0 from "myfile". getline myvar myfile Loads "myvar" from "myfile". command | getline Loads $0 from output of "command". command | getline myvar Loads "myvar" from output of "command".
- 一个相关的函数“close”允许关闭文件,以便再次从开头读取
close("myfile")
- 一个新函数“system”允许 Awk 程序调用系统命令
system("rm myfile")
- 命令行参数可以使用两个新的预定义变量 ARGC 和 ARGV 来解释,这是一种对 C 程序员来说立即熟悉的机制。ARGC(“参数计数”)给出命令行元素的数量,而 ARGV(“参数向量”)是一个数组,其条目分别存储元素。
- 存在一个新的条件赋值表达式,称为“?:”,其用法如下
status = (condition == "green")? "go" : "stop"
这转换为
if (condition=="green") {status = "go"} else {status = "stop"}
这种结构也应该对 C 程序员来说很熟悉。
- 有新的数学函数,例如三角函数和随机数函数
sin(x) Sine, with x in radians. cos(x) Cosine, with x in radians. atan2(y,z) Arctangent of y/x, in range -PI to PI. rand() Random number, with 0 <= number < 1. srand() Seed for random-number generator.
- 有新的字符串函数,例如匹配函数和替换函数
- match(<目标字符串>,<搜索字符串>)
在目标字符串中搜索搜索字符串;如果未匹配,则返回 0,如果匹配,则返回搜索字符串的起始索引。还将内置变量 RSTART 设置为起始索引,并将内置变量 RLENGTH 设置为匹配字符串的长度。 - sub(<正则表达式>,<替换字符串>)
在 $0 中搜索正则表达式的第一个匹配项并替换替换字符串。该函数返回所做替换的数量,就像其他替换函数一样。 - sub(<正则表达式>,<替换字符串>,<目标字符串>)
在目标字符串中搜索正则表达式的第一个匹配项并替换替换字符串。 - gsub(<正则表达式>,<替换字符串>)
在 $0 中搜索正则表达式的所有匹配项并替换替换字符串。 - sub(<正则表达式>,<替换字符串>,<目标字符串>)
在目标字符串中搜索正则表达式的所有匹配项并替换替换字符串。
- match(<目标字符串>,<搜索字符串>)
- 存在一种处理多维数组的机制。例如,以下程序创建并打印一个矩阵,然后打印该矩阵的转置
BEGIN {count = 1; for (row = 1; row <= 5; ++row) { for (col = 1; col <= 3; ++col) { printf("%4d",count); array[row,col] = count++; } printf("\n"); } printf("\n"); for (col = 1; col <= 3; ++col) { for (row = 1; row <= 5; ++row) { printf("%4d",array[row,col]); } printf("\n"); } exit; }
这会产生
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 4 7 10 13 2 5 8 11 14 3 6 9 12 15
Nawk 还包含一个新的“delete”函数,它删除数组元素
delete(array[count])
- 字符可以表示为八进制代码。例如,“\033”可用于定义“转义”字符。
- 一个新的内置变量 FNR 会跟踪当前文件的记录号,而不是 NR,NR 会跟踪当前输入行的记录号,而不管有多少文件贡献了该输入。它的行为与 NR 完全相同。
- 虽然 Nawk 确实有一些有用的改进,但它们通常旨在支持复杂程序的开发。我的感觉是,对于除了最专注的 Awk 用户之外的所有用户来说,Nawk 都过于复杂,而且无论如何都需要一个单独的文档才能充分说明其功能。那些想要了解有关 Nawk 更多信息的人,可以阅读 Aho/Weinberger/Kernighan 撰写的《AWK 编程语言》。这本简短、简洁、详细的书籍概述了 Nawk 的功能,并提供了使用它的复杂示例。