跳转到内容

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,新值将存在。NRNF 也是如此——更改它们的值会影响您的程序,如果它读取这些变量,但它不会影响 Awk 的行为。

  • 编写地址簿程序。您需要将 FS 设置为换行符,将 RS 设置为空行。您的程序应该读取多行输入并在单行格式中输出它。
  • 编写一个程序,该程序读取数字列表并将它们输出为不同的格式。每个输入行都应该以逗号或连字符之类的字符开头,后面跟着空格,然后最多五个数字(空格分隔)。您的程序应该输出这些数字,并在它们之间使用新的分隔符(在行的开头给出)。您需要为每一行输入修改 OFS

继续到下一页,了解 Awk 强大的关联数组

华夏公益教科书