一. AWK入门指南
Awk是一种便于使用且表达能力强的程序设计语言,可应用于各种计算和数据处理任务。本章是个入门指南,让你能够尽快地开始编写你自己的程序。第二章将描述整个语言,而剩下的章节将向你展示如何使用Awk来解决许多不同方面的问题。纵观全书,我们尽量选择了一些对你有用、有趣并且有指导意义的实例。
1.1 起步
有用的awk程序往往很简短,仅仅一两行。假设你有一个名为 emp.data 的文件,其中包含员工的姓名、薪资(美元/小时)以及小时数,一个员工一行数据,如下所示:
Beth | 4.00 | 0 |
Dan | 3.75 | 0 |
kathy | 4.00 | 10 |
Mark | 5.00 | 20 |
Mary | 5.50 | 22 |
Susie | 4.25 | 18 |
现在你想打印出工作时间超过零小时的员工的姓名和工资(薪资乘以时间)。这种任务对于awk来说就是小菜一碟。输入这个命令行就可以了::
awk '$3 >0 { print $1, $2 * $3 }' emp.data
你应该会得到如下输出:
该命令行告诉系统执行引号内的awk程序,从输入文件 emp.data 获取程序所需的数据。引号内的部分是个完整的awk程序,包含单个模式-动作语句。模式 $3>0 用于匹配第三列大于0的输入行,动作:
{ print $1, $2 * $3 }
打印每个匹配行的第一个字段以及第二第三字段的乘积。
如果你想打印出还没工作过的员工的姓名,则输入命令行::
awk '$3 == 0 { print $1 }' emp.data
这里,模式 $3 == 0 匹配第三个字段等于0的行,动作:
{ print $1 }
打印该行的第一个字段。
当你阅读本书时,应该尝试执行与修改示例程序。大多数程序都很简短,所以你能快速理解awk是如何工作的。在Unix系统上,以上两个事务在终端里看起来是这样的:
行首的 $ 是系统提示符,也许在你的机器上不一样。
AWK程序的结构
让我们回头看一下到底发生了什么事情。上述的命令行中,引号之间的部分是awk编程语言写就的程序。本章中的每个awk程序都是一个或多个模式-动作语句的序列:
awk的基本操作是一行一行地扫描输入,搜索匹配任意程序中模式的行。词语“匹配”的准确意义是视具体的模式而言,对于模式 $3 >0 来说,意思是“条件为真”。
每个模式依次测试每个输入行。对于匹配到行的模式,其对应的动作(也许包含多步)得到执行,然后读取下一行并继续匹配,直到所有的输入读取完毕。
上面的程序都是模式与动作的典型示例。:
$3 == 0 { print $1 }
是单个模式-动作语句;对于第三个字段为0的每行,打印其第一个字段。
模式-动作语句中的模式或动作(但不是同时两者)都可以省略。如果某个模式没有动作,例如::
$3 == 0
那么模式匹配到的每一行(即,对于该行,条件为真)都会被打印出来。该程序会打印 emp.data 文件中第三个字段为0的两行
如果有个没有模式的动作,例如::
{ print $1 }
那么这种情况下的动作会打印每个输入行的第一列。
由于模式和动作两者任一都是可选的,所以需要使用大括号包围动作以区分于其他模式。
执行AWK程序
执行awk程序的方式有多种。你可以输入如下形式的命令行::
awk 'program' input files
从而在每个指定的输入文件上执行这个program。例如,你可以输入::
awk '$3 == 0 { print $1 }' file1 file2
打印file1和file2文件中第三个字段为0的每一行的第一个字段。
你可以省略命令行中的输入文件,仅输入::
awk 'program'
这种情况下,awk会将program应用于你在终端中接着输入的任意数据行,直到你输入一个文件结束信号(Unix系统上为control-d)。如下是Unix系统的一个会话示例:
Beth
Dan
Kathy
加粗的字符是计算机打印的。
这个动作非常便于尝试awk:输入你的程序,然后输入数据,观察发生了什么。我们再次鼓励你尝试这些示例并进行改动。
注意命令行中的程序是用单引号包围着的。这会防止shell解释程序中 $ 这样的字符,也允许程序的长度超过一行。
当程序比较短小(几行的长度)的时候,这种约定会很方便。然而,如果程序较长,将程序写到一个单独的文件中会更加方便。假设存在程序 progfile ,输入命令行::
awk -f progfile optional list of input files
其中 -f 选项指示awk从指定文件中获取程序。可以使用任意文件名替换 progfile 。
错误
如果你的awk程序存在错误,awk会给你一段诊断信息。例如,如果你打错了大括号,如下所示::
awk '$3 == 0 [ print $1 }' emp.data
你会得到如下信息:
“Syntax error”意味着在 >>> <<< 标记的地方检测到语法错误。“Bailing out”意味着没有试图恢复。有时你会得到更多的帮助-关于错误是什么,比如大括号或括弧不匹配。
因为存在句法错误,awk就不会尝试执行这个程序。然而,有些错误,直到你的程序被执行才会检测出来。例如,如果你试图用零去除某个数,awk会在这个除法的地方停止处理并报告输入行的行号以及在程序中的行号(这话是什么意思?难道输入行的行号是忽略空行后的行号?)。
更详细请看源地址http://awk.readthedocs.io/en/latest/chapter-one.html