Awk 入门/变量
如前所述,Awk 支持用户定义的变量和它自己的预定义变量。任何以字母开头,由字母数字字符或下划线 (_
) 组成的标识符都可以用作变量名,前提是它不与 Awk 的保留字冲突。显然,变量名中不允许出现空格;这会造成太多混淆。注意,使用保留字是构建 Awk 程序时的常见错误,因此,如果程序在看似无害的单词上崩溃,请尝试将其更改为更不寻常的名称,看看问题是否消失。
无需声明变量,事实上也无法声明,虽然在一个复杂的 Awk 程序中,在 BEGIN
子句中初始化变量是一个好主意,以使它们更清晰,并确保它们具有正确的初始值。依赖默认值是任何编程语言中的一个坏习惯,尽管在 Awk 中,所有变量都以零(如果用作数字)或空字符串的值开始。Awk 中没有声明变量的事实也会导致一些奇怪的错误,例如拼错变量名,并且没有意识到这已经创建了第二个不同的变量,该变量与程序的其余部分不同步。
同样如前所述,Awk 是弱类型的。变量没有数据类型,因此它们可以用来存储字符串或数值;对变量的字符串操作将产生字符串结果,数字操作将产生数字结果。如果文本字符串看起来不像数字,它在数字操作中将被简单地视为 0。Awk 有时会因为这个问题而造成混淆,因此程序员必须记住这一点,并避免潜在的陷阱。例如
var = 1776
var = "1776"
这两个例子是相同的——它们都将值 1776 加载到名为 var
的变量中。这两种情况下都可以将其视为计算中的数值,也可以对其执行字符串操作。如果 var
加载了以下形式的文本字符串
var = "somestring"
可以对其执行字符串操作,但它在数字操作中将计算为 0。如果将此示例更改如下
var = somestring
现在,这将始终针对字符串和数字操作返回 0——因为 Awk 认为没有引号的 somestring
是未初始化变量的名称。顺便说一句,可以测试未初始化变量是否为 0
var == 0
如果 var
没有初始化,则此测试将返回“true”;但是,奇怪的是,尝试 print
未初始化的变量不会返回任何内容。例如
print something
这只会打印一个空行,而
something = 0; print something
这将打印一个“0”。
与许多其他语言不同,Awk 字符串变量不表示为字符的一维数组。但是,可以使用 substr()
函数访问字符串中的字符。有关数组和字符串处理函数的更多信息将在后面介绍。
Awk 的内置变量包括字段变量——$1
、$2
、$3
等($0
是整行)——它们将一行文本分解为称为字段的单个单词或片段。很快,我们将看到更高级的 Awk 程序如何操作多行数据,例如邮寄地址列表。
但是,Awk 还有几个内置变量。其中一些可以通过使用赋值运算符进行更改。例如,编写 FS=":"
将将字段分隔符更改为冒号。从那时起,字段变量将引用当前行中每个冒号分隔的部分。
NR
:保持输入记录数量的当前计数。请记住,记录通常是行;Awk 对文件中每条记录执行一次模式/动作语句。NF
:保持当前输入记录中字段数量的计数。请记住,字段默认情况下是空格分隔的单词,但本质上是数据的“列”,如果您的输入文件格式类似于表格。可以使用$NF
访问输入行中的最后一个字段。FILENAME
:包含当前输入文件的名称。FS
:包含用于在输入行上划分字段的字段分隔符字符。默认值为“空格”,即空格和制表符字符。FS
可以重新分配给另一个字符(通常在BEGIN
中)以更改字段分隔符。RS
:存储当前记录分隔符字符。由于默认情况下,输入行是输入记录,因此默认记录分隔符字符是换行符。通过将FS
设置为换行符并将RS
设置为空行 (RS=""
),您可以处理多行数据。这将用于,例如,地址列表(每个地址占用多行)。OFS
:存储输出字段分隔符,它在 Awk 打印时将字段分隔开。默认值为空格。只要print
有几个用逗号分隔的参数,它将在每个参数之间打印OFS
的值。ORS
:存储输出记录分隔符,它在 Awk 打印时将输出行分隔开。默认值为换行符。print
会自动在它要打印的内容的末尾输出ORS
的内容。OFMT
:存储数字输出的格式。默认格式为“%.6g
”,将在讨论printf
时解释。ARGC
:存在的命令行参数数量。ARGV
:命令行参数列表。
顺便说一句,值可以加载到字段变量中;它们不是只读的。例如
$2 = "NewText"
这会将输入行中的第二个文本字段更改为“NewText”。它不会修改输入文件;别担心。这可以用作对输入文件行进行修改的技巧,然后只需使用 print
而不带任何参数来打印这些行。
再次,所有变量都可以修改,尽管某些内置变量不会产生预期的效果。例如,您可以更改 FILENAME
的值,但它不会加载新文件。Awk 只是照常继续,但如果访问 FILENAME
,新值将存在。NR
和 NF
也是如此——更改它们的值会影响您的程序,如果它读取这些变量,但它不会影响 Awk 的行为。
- 编写地址簿程序。您需要将
FS
设置为换行符,将RS
设置为空行。您的程序应该读取多行输入并在单行格式中输出它。 - 编写一个程序,该程序读取数字列表并将它们输出为不同的格式。每个输入行都应该以逗号或连字符之类的字符开头,后面跟着空格,然后最多五个数字(空格分隔)。您的程序应该输出这些数字,并在它们之间使用新的分隔符(在行的开头给出)。您需要为每一行输入修改
OFS
。
继续到下一页,了解 Awk 强大的关联数组。