二. AWK语言详解

本章将主要通过示例来解释构成awk程序的概念。因为这是对语言的全面描述,材料会很详细,因此我们推荐你浏览略读,需要的时候再回来核对细节。

最简单的awk程序就是一个模式-动作语句的序列::

pattern    { action }
pattern    { action }
...

某些语句中,可能没有模式;另一些语句中,可能没有动作及其大括号。awk检查你的程序以确认不存在语法错误后,一次读取一行输入,并对每一行按序处理模式。对于每个匹配到当前输入行的模式,执行其关联的动作。不存在模式,则匹配每个输入行,因此没有模式的每个动作对于每个输入行都要执行。一个仅包含模式的模式-动作语句将打印匹配该模式的每个输入行。本章的大部分内容中,名词”输入行(input-line)”和”记录(record)” 是同义的。2.5小节中,我们将讨论多行记录,即一个记录包含多行输入。

本章的第一节将详细描述模式。第二节通过表达式、赋值以及控制语句来描述动作。剩下的章节覆盖函数定义,输出,输入,以及awk程序如何调用其他程序等内容。多数章节包含了主要特性的概要。

输入文件 countries

本章中,我们使用一个名为 countries 的文件作为许多awk程序的输入。文件的每行包含一个国家的名字,以千平方英里为单位的面积,以百万为单位的人口数,以及属于哪个洲。数据是1984年的,苏联(USSR)被武断地归入了亚洲。文件中,四列数据以制表符tab分隔;以单个空格将 NorthSouthAmerica 分隔开。

文件 countries 包含如下数据行::

USSR    8649    275     Asia
Canada  3852    25      North America
China   3705    1032    Asia
USA     3615    237     North America
Brazil  3286    134     South America
India   1267    746     Asia
Mexico  762     78      North America
France  211     55      Europe
Japan   144     120     Asia
Germany 96      61      Europe
England 94      56      Europe

本章的其余部分,如果没有明确说明输入文件,那么就是使用文件 countries

程序的格式

模式-动作语句以及动作中的语句通常以换行分隔,如果它们以分号分隔,则多个语句可以出现在一行中。分号可以放在任意语句的尾部。

动作的开大括号必须与其对应的模式处于同一行;动作的其余部分,包括闭大括号,则可以出现接下来的行中。

空行会被忽略;一般为了提高程序的可读性会在语句的前面或者后面插入空行。在操作符和操作数的两边插入空格和制表符也是为了提高可读性。

任意行的末尾可能会有注释。注释以符号 # 开始,结束于行尾,就像这样

{ print $1, $3 }        # print country name and population

长语句可以跨越多行,但要在断行的地方加入一个反斜杠和一个换行符::

{ print \
                $1,             # country name
                $2,             # area in thousands of square miles
                $3 }    # population in millions

如上例所示,语句也可以逗号断行,在每个断行的末尾也可以加入注释。

本书中,我们使用了多种格式风格,部分是为了说明相异之处,部分是为了避免程序占用太多的行空间。类似于本章中的简短程序,格式并不是很重要,但一致性与可读性可以帮助更长的程序保持可控。

2.1 模式

模式控制着动作的执行:模式匹配,其关联的动作则执行。本节将描述6种模式及其匹配条件。


模式摘要

1. BEGIN { 语句 }
在读取任何输入前执行一次 语句
2. END { 语句 }
读取所有输入之后执行一次 语句
3. 表达式 { 语句 }
对于 表达式 为真(即,非零或非空)的行,执行 语句
4. /正则表达式/ { 语句 }
如果输入行包含字符串与 正则表达式 相匹配,则执行 语句
5. 组合模式 { 语句 }
一个 组合模式 通过与(&&),或(||),非(|),以及括弧来组合多个表达式;对于组合模式为真的每个输入行,执行 语句
6. 模式1,模式2 { 语句 }
范围模式(range pattern)匹配从与 模式1 相匹配的行到与 模式2 相匹配的行(包含该行)之间的所有行,对于这些输入行,执行 语句

BEGIN和END不与其他模式组合。范围模式不可以是任何其他模式的一部分。BEGIN和END是仅有的必须搭配动作的模式。