gawk - 模式扫描和处理语言
概要
gawk [POSIX 或 GNU 样式的选项] -f program-file [ -- ] file ...
gawk [POSIX 或 GNU 样式的选项] [ -- ] program-text file ...
首先阅读
此手册页仅供参考。 gawk 的唯一权威来源是 Texinfo 手册,它以多种格式在线提供,网址为 https://www.gnu.org/software/gawk/manual。 它也可以安装在系统的 Info 子系统中,因此可以通过 info(1) 命令获得。
如果 Texinfo 手册和此手册页之间存在任何矛盾,则应将手册视为具有权威性。
描述
Gawk 是 GNU 项目的 AWK 编程语言的实现。 它符合 POSIX 1003.1 标准中语言的定义。 此版本反过来基于 Aho、Kernighan 和 Weinberger 的《AWK 编程语言》中的描述。 Gawk 提供了当前版本的 Brian Kernighan 的 awk 中以及许多 GNU 特定扩展中找到的附加功能。
命令行由 gawk 本身的选项、AWK 程序文本(如果未通过 -f 或 --include 选项提供)以及要设置为 AWK 预定义变量 ARGC 和 ARGV 中的值组成。
前言
此手册页有意尽可能简洁。 完整的详细信息请参见 GAWK:有效的 AWK 编程,您应该在那里查找任何特定功能的完整信息。 在可能的情况下,提供了指向在线手册版本的链接。
选项格式
Gawk 选项可以是传统的 POSIX 样式的单字母选项,也可以是 GNU 样式的长选项。 POSIX 选项以单个“-”开头,而长选项以“--”开头。 长选项用于 GNU 特定功能和 POSIX 强制功能。
Gawk 特定的选项通常以长选项的形式使用。 长选项的参数要么通过“=”号连接到选项,中间没有空格,要么可以在下一个命令行参数中提供。 只要缩写仍然是唯一的,长选项就可以缩写。
此外,每个长选项都有一个相应的短选项,因此可以在 #!可执行脚本中使用该选项的功能。
选项
Gawk 接受以下选项。 首先列出标准选项,然后列出 gawk 扩展的选项,按短选项字母顺序排列。
-f program-file, --file program-file
从文件 program-file 读取 AWK 程序源代码,而不是从第一个命令行参数读取。 可以使用多个 -f 选项。 使用 -f 读取的文件被视为以隐式的 @namespace "awk" 语句开头。
-F fs, --field-separator fs
使用 fs 作为输入字段分隔符(FS 预定义变量的值)。
-v var=val, --assign var=val
在程序开始执行之前,将值 val 分配给变量 var。这些变量值可供 AWK 程序的 BEGIN 规则使用。
-b, --characters-as-bytes
将所有输入数据视为单字节字符。--posix 选项将覆盖此选项。
-c, --traditional
以兼容模式运行。在兼容模式下,gawk 的行为与 Brian Kernighan 的 awk 相同;不识别任何 GNU 特定的扩展。
-C, --copyright
将 GNU 版权信息的简短版本打印到标准输出并成功退出。
-d[file], --dump-variables[=file]
打印排序后的全局变量列表、它们的类型以及最终值到文件。默认文件是当前目录中的 awkvars.out。
-D[file], --debug[=file]
启用 AWK 程序的调试。默认情况下,调试器从键盘(标准输入)以交互方式读取命令。可选的文件参数指定一个包含调试器要以非交互方式执行的命令列表的文件。
在这种执行模式下,gawk 加载 AWK 源代码,然后提示输入调试命令。gawk 只能调试使用 -f 和 --include 选项提供的 AWK 程序源代码。调试器在 GAWK:Effective AWK Programming 中有文档说明;请参阅 https://www.gnu.org/software/gawk/manual/html_node/Debugger.html#Debugger。
-e program-text, --source program-text
使用 program-text 作为 AWK 程序源代码。通过 -e 提供的每个参数都将被视为以隐式 @namespace "awk" 语句开头。
-E file, --exec file
类似于 -f,但是,此选项是最后处理的。这应该用于带有 #! 脚本,特别是用于 CGI 应用程序,以避免从 URL 中传递命令行选项或源代码。此选项禁用命令行变量赋值。
-g, --gen-pot
扫描并解析 AWK 程序,并生成一个 GNU .pot(Portable Object Template)格式的文件到标准输出,其中包含程序中所有可本地化字符串的条目。程序本身不会执行。
-h, --help
将可用的选项的相对简短的摘要打印到标准输出。根据 GNU 编码标准,这些选项会导致立即成功退出。
-i include-file, --include include-file
加载 awk 源代码库。这会使用 AWKPATH 环境变量搜索库。如果初始搜索失败,将进行另一次尝试,方法是在文件名后附加 .awk 后缀。该文件将仅加载一次(即,消除重复项),并且代码不构成主程序源代码。使用 --include 读取的文件被视为以隐式 @namespace "awk" 语句开头。
-I, --trace
在程序运行时,打印正在执行的内部字节码名称。跟踪输出到标准错误。每个“操作码”在输出中都以加号 (+) 开头。
-k, --csv
启用 CSV 特殊处理。有关更多详细信息,请参阅“逗号分隔值”。
-l lib, --load lib
从共享库 lib 加载 gawk 扩展。这使用 AWKLIBPATH 环境变量搜索库。如果第一次搜索失败,则将进行另一次尝试,并在之后附加平台的默认共享库后缀。库初始化例程的名称应为 dl_load()。
-L [value], --lint[=value]
提供有关构造的警告,这些构造可能存在问题或不能移植到其他 AWK 实现。有关 value 的可能值的列表,请参阅 https://www.gnu.org/software/gawk/manual/html_node/Options.html#Options 。
-M, --bignum
强制对数字执行任意精度算术。如果 gawk 未编译以使用 GNU MPFR 和 GMP 库,则此选项无效。(在这种情况下,gawk 会发出警告。)
注意:此功能处于测试阶段。主要 gawk 维护者不再支持它,尽管开发团队中有一名成员在支持。如果这种情况发生变化,此功能将从 gawk 中删除。
-n, --non-decimal-data
识别输入数据中的八进制和十六进制值。请谨慎使用此选项!
-N, --use-lc-numeric
强制 gawk 在解析输入数据时使用区域设置的十进制点字符。
-o[file], --pretty-print[=file]
将程序的格式化版本输出到文件。默认文件是在当前目录中的 awkprof.out。此选项意味着 --no-optimize。
-O, --optimize
启用 gawk 对程序内部表示形式的默认优化。此选项默认启用。
-p[prof-file], --profile[=prof-file]
启动分析会话,并将分析数据发送到 prof-file。默认是在当前目录中的 awkprof.out。分析包含程序中每个语句的执行计数(在左侧边距)以及每个用户定义函数的函数调用计数。在这种模式下,gawk 的运行速度会变慢。此选项意味着 --no-optimize。
-P, --posix
这将启用兼容模式,并禁用许多常见的扩展。
-r, --re-interval
启用在正则表达式匹配中使用区间表达式。默认情况下启用区间表达式,但此选项保留以用于向后兼容。
-s, --no-optimize
禁用 gawk 对程序内部表示形式的默认优化。
-S, --sandbox
以沙盒模式运行 gawk,禁用 system() 函数、使用 getline 进行输入重定向、使用 print 和 printf 进行输出重定向以及加载动态扩展。命令执行(通过管道)也被禁用。
-t, --lint-old
提供警告,指出代码中存在哪些不兼容于原始 UNIX awk 版本的结构。
-V, --version
在标准输出中打印此 gawk 副本的版本信息。这对于报告错误很有用。根据 GNU 编码标准,这些选项会导致立即成功退出。
--
标记选项的结束。这对于允许 AWK 程序本身从以“-”开头的参数开始很有用。
在兼容模式下,任何其他选项都会被标记为无效,但实际上会被忽略。在正常操作中,只要提供了程序文本,未知的选项就会传递到 AWK 程序中,并存储在 ARGV 数组中以供处理。
为了实现 POSIX 兼容性,可以使用 -W 选项,后跟长选项的名称。
AWK 程序执行
一个 AWK 程序由一系列可选的指令、模式-动作语句和可选的函数定义组成。
@include "filename"
@load "filename"
@namespace "name"
pattern { 动作语句 }
function name(参数列表) { 语句 }
Gawk 首先从程序文件(如果指定)、从 --source 选项的参数或从命令行中的第一个非选项参数中读取程序源代码。-f 和 --source 选项可以在命令行中多次使用。Gawk 将程序文本读取为所有程序文件和命令行源代码文本连接在一起。
此外,可以使用以 @include 开头的行将其他源代码文件包含到程序中。这等效于使用 --include 选项。
可以使用以 @load 开头的行将扩展函数加载到程序中。这等效于使用 --load 选项。
环境变量 AWKPATH 指定用于查找由 -f 和 --include 选项指定的源代码文件的搜索路径。如果此变量不存在,则默认路径为 ".:/usr/local/share/awk"。(实际目录可能会因 gawk 的构建和安装方式而异。)如果传递给 -f 选项的文件名包含“/”字符,则不会执行路径搜索。
环境变量 AWKLIBPATH 指定用于查找由 --load 选项指定的源代码文件的搜索路径。如果此变量不存在,则默认路径为 /usr/local/lib/gawk。(实际目录可能会因 gawk 的构建和安装方式而异。)
Gawk 以以下顺序执行 AWK 程序。首先,通过 -v 选项指定的所有变量赋值都会执行。接下来,gawk 将程序编译成内部形式。然后,gawk 执行 BEGIN 规则(如果有的话)中的代码,然后开始读取 ARGV 数组中命名的每个文件(最多到 ARGV[ARGC-1])。如果没有在命令行中命名文件,gawk 会读取标准输入。
如果命令行上的文件名形式为 var=val,则将其视为变量赋值。变量 var 将被赋值为 val。(这在任何 BEGIN 规则之后发生。)
如果 ARGV 的某个元素的value为空(""),gawk会跳过该元素。
对于每个输入文件,如果存在 BEGINFILE 规则,gawk会在处理文件内容之前执行关联的代码。 类似地,gawk会在处理完文件后执行与 ENDFILE 规则关联的代码。
对于输入中的每一条记录,gawk会检查该记录是否与 AWK 程序中的任何模式匹配。对于匹配的每个模式,gawk会执行关联的操作。模式的测试顺序与它们在程序中出现的顺序相同。
最后,在处理完所有输入后,gawk会执行 END 规则中的代码(如果有)。
命令行目录
根据 POSIX 标准,awk 命令行中指定的文件必须是文本文件。如果不是,则行为是“未定义的”。大多数版本的 awk 将命令行中的目录视为致命错误。
对于 gawk,命令行中的目录会产生一个警告,但除此之外不会有其他影响。如果给定了 --posix 或 --traditional 选项,则 gawk 会恢复到将命令行中的目录视为致命错误的处理方式。
变量、记录和字段
AWK 变量是动态的;它们在第一次使用时才存在。它们的值可以是浮点数或字符串,或者两者兼有,具体取决于它们的使用方式。 此外,gawk 允许变量具有正则表达式类型。AWK 还有一维数组;可以使用多维数组,但是 gawk 提供了真正的多维数组。 几个预定义的变量在程序运行时被设置;这些变量将在需要时进行描述,并在下面进行总结。
记录
通常,记录由换行符分隔。 可以通过为内置变量 RS 分配值来控制记录的分隔方式。有关详细信息,请参阅 [https://www.gnu.org/software/gawk/manual/html_node/Records.html]。
字段
当读取每个输入记录时,gawk 会使用变量 FS 的值作为字段分隔符,将记录拆分为字段。 此外,FIELDWIDTHS 和 FPAT 可用于控制输入字段的拆分。 有关详细信息,请参阅 [https://www.gnu.org/software/gawk/manual/html_node/Fields.html]。
输入记录中的每个字段都可以通过其位置引用:$1、$2,依此类推。 $0 是整个记录,包括前导和尾随空格。
变量 NF 设置为输入记录中的字段总数。
引用不存在的字段(即,$NF 之后的字段)会产生空字符串。 但是,分配给不存在的字段(例如,$(NF+2) = 5)会增加 NF 的值,创建具有空字符串作为其值的任何中间字段,并导致重新计算 $0 的值,字段之间用 OFS 的值分隔。 引用负数编号的字段会导致致命错误。 减小 NF 会导致新值之后的字段的值丢失,并且重新计算 $0 的值,字段之间用 OFS 的值分隔。
为现有字段赋值会导致整个记录在引用 $0 时被重建。 类似地,为 $0 赋值会导致记录被重新拆分,从而为字段创建新的值。
逗号分隔值
当使用 -k 或 --csv 选项调用时,gawk 不使用上述描述的常规记录确定和字段拆分。 相反,记录由未引用的换行符分隔,字段由逗号分隔。 可以使用双引号来包含包含逗号、换行符或双重双引号的字段。 更多详细信息,请参见 https://www.gnu.org/software/gawk/manual/html_node/Comma-Separated-Fields.html。
内置变量
Gawk 的内置变量如下列出。 此列表有意简洁。 有关详细信息,请参见 https://www.gnu.org/software/gawk/manual/html_node/Built_002din-Variables.
ARGC 命令行参数的数量。
ARGIND 当前正在处理的文件的 ARGV 中的索引。
ARGV 命令行参数的数组。 该数组的索引从 0 到 ARGC - 1。
BINMODE 在非 POSIX 系统上,指定对所有文件 I/O 使用“二进制”模式。 有关详细信息,请参见 https://www.gnu.org/software/gawk/manual/html_node/PC-Using.html。
CONVFMT 数字的转换格式,默认值为 "%.6g"。
ENVIRON 一个数组,包含当前环境的值。 该数组的索引是环境变量,每个元素都是该变量的值。
ERRNO 如果系统错误发生在 getline 的重定向期间、getline 的读取期间或 close() 期间,则 ERRNO 将设置为描述该错误的字符串。 该值可能在非英语区域设置中发生翻译。
FIELDWIDTHS 一个由空格分隔的字段宽度列表。 设置后,gawk 将输入解析为固定宽度的字段,而不是使用 FS 变量的值作为字段分隔符。 每个字段宽度可以选择性地由冒号分隔的值前缀,该值指定在字段开始之前要跳过的字符数。
FILENAME 当前输入文件的名称。 如果命令行中未指定任何文件,则 FILENAME 的值为“-” 。 但是,FILENAME 在 BEGIN 规则中未定义(除非由 getline 设置)。
FNR 当前输入文件中输入记录的编号。
FPAT 一个描述记录中字段内容的正则表达式。 设置后,gawk 将输入解析为字段,其中字段与正则表达式匹配,而不是使用 FS 的值作为字段分隔符。
FS 输入字段分隔符,默认值为一个空格。 有关详细信息,请参见 https://www.gnu.org/software/gawk/manual/html_node/Field-Separators.html。
FUNCTAB 一个数组,其索引和对应的值是程序中所有用户定义或扩展函数的名字。注意:您不能使用 delete 语句与 FUNCTAB 数组一起使用。
IGNORECASE 控制所有正则表达式和字符串操作的大小写敏感性。请参见 https://www.gnu.org/software/gawk/manual/html_node/Case_002dsensitivity.html 以获取更多详细信息。
LINT 从 AWK 程序内部提供对 --lint 选项的动态控制。
NF 当前输入记录中的字段数。
NR 到目前为止看到的输入记录总数。
OFMT 数字的输出格式,默认为“%.6g”。
OFS 输出字段分隔符,默认为空格。
ORS 输出记录分隔符,默认为换行符。
PREC 任意精度浮点数的运算精度,默认为 53。
PROCINFO 此数组的元素提供对正在运行的 AWK 程序的信息的访问。请参见 https://www.gnu.org/software/gawk/manual/html_node/Auto_002dset 以获取更多详细信息。
ROUNDMODE 用于数字上任意精度算术的舍入模式,默认为“N”(IEEE-754 roundTiesToEven 模式)。请参见 https://www.gnu.org/software/gawk/manual/html_node/Setting-the-rounding-mode 以获取更多详细信息。
RS 输入记录分隔符,默认为换行符。
RT 记录终止符。Gawk 将 RT 设置为与 RS 中指定的字符或正则表达式匹配的输入文本。
RSTART match() 匹配的第一个字符的索引;如果没有匹配,则为 0。
RLENGTH match() 匹配的字符串的长度;如果没有匹配,则为 -1。
SUBSEP 用于分隔数组元素中多个下标的字符串,默认为“\\034”。
SYMTAB 一个数组,其索引是程序中所有当前定义的全局变量和数组的名称。您不能使用 delete 语句与 SYMTAB 数组一起使用,也不能分配给索引不是变量名的元素。
TEXTDOMAIN AWK 程序的文本域;用于查找程序的本地化翻译。
数组
数组使用方括号 ([ 和 ]) 中的表达式来索引。如果表达式是表达式列表(expr, expr ...),则数组下标是包含每个表达式(字符串)值的字符串,由 SUBSEP 变量的值分隔。
此功能用于模拟多维数组。例如:
i = "A"; j = "B"; k = "C"
x[i, j, k] = "hello, world\n"
将字符串“hello, world\n”分配给数组 x 的元素,该元素的索引是字符串“A\\034B\\034C”。AWK 中的所有数组都是关联数组,即,由字符串值进行索引。
可以使用 in 运算符来测试数组是否具有由特定值组成的索引:
if (val in array)
print array[val]
如果数组有多个下标,请使用 (i, j) in array。
^ n 构造也可以用于 for 循环,以迭代数组的所有元素。
但是,(i, j) in array 构造只能在测试中使用,不能在 for 循环中使用。
可以使用 delete 语句从数组中删除元素。delete 语句也可以用于删除数组的所有内容,只需指定数组名称而无需下标。
gawk 支持真正的多维数组。它不需要像 C 或 C++ 中那样,使这些数组“矩形”。请参阅 [https://www.gnu.org/software/gawk/manual/html_node/Arrays] 以获取更多详细信息。
命名空间
gawk 提供了一个简单的命名空间机制,以帮助解决 AWK 中所有变量都是全局变量的问题。
限定名称由两个简单标识符组成,中间用双冒号 (::) 分隔。左侧的标识符表示命名空间,右侧的标识符是命名空间中的变量。所有简单的(非限定的)名称都被认为是位于“当前”命名空间中;默认命名空间是 awk。但是,仅由大写字母组成的简单标识符会被强制放入 awk 命名空间中,即使当前命名空间不同。
可以使用 @namespace "name" 指令来更改当前命名空间。
标准预定义的内置函数名称不能用作命名空间名称。gawk 提供的其他函数的名称可以用作命名空间名称,也可以用作其他命名空间中的简单标识符。有关更多详细信息,请参阅 [https://www.gnu.org/software/gawk/manual/html_node/Namespaces.html#Namespaces]。
变量类型和转换
变量和字段可以是(浮点)数字、字符串或两者兼有。它们也可以是正则表达式。变量的值的解释取决于其上下文。如果变量用于数值表达式中,则将其视为数字;如果将其用作字符串,则将其视为字符串。
要强制变量被视为数字,请将其与零相加;要强制其被视为字符串,请将其与空字符串连接。
未初始化的变量的数值为零,字符串值为 ""(空字符串)。
当必须将字符串转换为数字时,使用 strtod(3) 进行转换。数字转换为字符串是通过使用 CONVFMT 的值作为 sprintf(3) 的格式字符串,并将变量的数值作为参数来完成的。但是,尽管 AWK 中的所有数字都是浮点数,但整数值始终以整数形式转换。
gawk 执行以下比较:如果两个变量都是数值,则对其进行数值比较。如果一个值是数值,另一个值是“数值字符串”,则也进行数值比较。否则,将数值转换为字符串,并执行字符串比较。两个字符串当然以字符串形式进行比较。
请注意,字符串常量,例如“57”,不是数值字符串,它们是字符串常量。
“数值字符串”的概念仅适用于字段、getline输入、FILENAME、ARGV元素和通过split()或patsplit()创建的数组的元素,这些元素是数值字符串。基本思想是,用户输入,并且只有用户输入,如果看起来是数值,则应该将其视为数值。
八进制和十六进制常量
您可以在 AWK 程序的源代码中使用 C 风格的八进制和十六进制常量。例如,八进制值 011 等于十进制 9,十六进制值 0x11 等于十进制 17。
字符串常量
AWK 中的字符串常量是包含在双引号(如“value”)中的字符序列。在字符串中,某些转义序列会被识别,就像在 C 中一样。请参阅 [https://www.gnu.org/software/gawk/manual/html_node/Escape-Sequences] 以获取详细信息。
正则表达式常量
正则表达式常量是包含在正斜杠(如 /value/)之间的字符序列。
转义序列也可以在常量正则表达式(例如,/[ \t\f\n\r\v]/ 匹配空格字符)中使用(例如,/[ \t\f\n\r\v]/ 匹配空格字符)。
Gawk 提供了强类型的正则表达式常量。这些常量以一个前导 @ 符号(例如:@/value/)开头。这样的常量可以分配给标量(变量、数组元素)并传递给用户定义的函数。分配了这些常量的变量具有正则表达式类型。
模式和动作
AWK 是一种面向行的语言。模式先出现,然后是动作。动作语句包含在 { 和 } 中。模式或动作可以省略,但不能同时省略。如果省略模式,则动作将对每个输入记录执行。省略动作等效于:
{ print }
这将打印整个记录。
注释以井号 (#) 字符开头,并持续到行尾。可以使用空行来分隔语句。通常,语句以换行符结尾,但对于以逗号、{、?、:、&& 或 || 结尾的行,这不是必需的。以 do 或 else 结尾的行,其语句也会自动延续到下一行。在其他情况下,可以通过以“\"结尾来延续一行,在这种情况下,将忽略换行符。但是,# 字符后面的“\"不是特殊的。
可以通过使用分号(;)分隔语句来将多个语句放在同一行上。这适用于模式-动作对中动作部分(通常情况)的语句,以及模式-动作语句本身。
模式
AWK 模式可以是以下之一:
BEGIN
END
BEGINFILE
ENDFILE
/正则表达式/
关系表达式
模式 && 模式
模式 || 模式
模式 ? 模式 : 模式
(模式)
! 模式
模式1, 模式2
BEGIN 和 END 是两种特殊的模式,它们不与输入进行匹配。所有 BEGIN 模式的动作部分都会合并,就好像所有语句都写在一个 BEGIN 规则中一样。它们在读取任何输入之前执行。类似地,所有 END 规则都会合并,并在耗尽所有输入(或者执行退出语句时)执行。BEGIN 和 END 模式不能与其他模式组合成模式表达式。BEGIN 和 END 模式不能缺少动作部分。
BEGINFILE 和 ENDFILE 是另外两种特殊模式,它们的动作在读取每个命令行输入文件的第一个记录之前和读取最后一个记录之后执行。在 BEGINFILE 规则中,如果文件已成功打开,ERRNO 的值为一个空字符串。否则,文件存在一些问题,代码应该使用 nextfile 来跳过它。如果未这样做,gawk 会产生其通常的致命错误,用于处理无法打开的文件。
对于 /正则表达式/ 模式,相关的语句将为匹配该正则表达式的每个输入记录执行。正则表达式基本上与 egrep(1) 中的正则表达式相同。有关正则表达式的详细信息,请参见 [https://www.gnu.org/software/gawk/manual/html_node/Regexp.html]。
关系表达式可以使用下面在“动作”部分中定义的任何运算符。这些运算符通常用于测试某些字段是否与某些正则表达式匹配。
&&、|| 和 ! 运算符分别是逻辑 AND、逻辑 OR 和逻辑 NOT,与 C 语言中的运算符相同。它们也像 C 语言一样进行短路求值,用于组合更简单的模式表达式。与大多数语言一样,可以使用括号来更改求值顺序。
?: 运算符与 C 语言中的运算符相同。如果第一个模式为真,则用于测试的模式是第二个模式,否则是第三个模式。仅评估第二个和第三个模式中的一个。
pattern1, pattern2 形式的表达式称为范围模式。它匹配从匹配 pattern1 的记录开始,到匹配 pattern2 的记录结束的所有输入记录(包括)。它不能与其他类型的模式表达式组合。
动作
动作语句用大括号 { 和 } 括起来。动作语句由通常的赋值、条件和循环语句组成,这些语句也存在于大多数语言中。可用的运算符、控制语句和输入/输出语句模仿了 C 语言中的运算符。
运算符
AWK 中的运算符,按优先级从高到低排列,如下所示:
(...) 分组
$ 字段引用。
++ -- 递增和递减,前缀和后缀形式。
^ 指数。
+ - ! 一元加、一元减和逻辑否定。
* / % 乘法、除法和模运算。
+ - 加法和减法。
space 字符串连接。
| |& 管道 I/O,用于 getline、print 和 printf。
< > <= >= == !=
标准的比较运算符。
~ !~ 正则表达式匹配,否定匹配。
in 数组成员。
&& 逻辑 AND。
|| 逻辑 OR。
?: C 语言的条件表达式。其形式为 expr1 ? expr2 : expr3。如果 expr1 为真,则表达式的值为 expr2,否则为 expr3。仅评估 expr2 或 expr3 中的一个。
= += -= *= /= %= ^=
赋值。支持绝对赋值(var = value)和运算符赋值(其他形式)。
控制语句
控制语句如下:
if (condition) statement [ else statement ]
while (condition) statement
do statement while (condition)
for (expr1; expr2; expr3) statement
for (var in array) statement
break
continue
delete array[index]
delete array
exit [ expression ]
{ statements }
switch (expression) {
case value|regex : statement
...
[ default: statement ]
}
I/O 语句
输入/输出语句如下:
close(file [, how]) 关闭打开的文件、管道或协程。可选的 how 仅在关闭双向管道到协程的一端时使用。它必须是一个字符串值,可以是 "to" 或 "from"。
getline 从下一个输入记录中设置 $0;设置 NF、NR、FNR、RT。
getline <file 从文件的下一个记录中设置 $0;设置 NF、RT。
getline var 从下一个输入记录中设置 var;设置 NR、FNR、RT。
getline var <file 从文件的下一个记录中设置 var;设置 RT。
command | getline [var]
运行命令,将输出管道输入到 $0 或 var 中,如上所述,以及 RT。
command |& getline [var]
运行命令作为协程,将输出管道输入到 $0 或 var 中,如上所述,以及 RT。(该命令也可以是套接字。请参阅下面的“特殊文件名”部分。)
fflush([file]) 刷新与打开的输出文件或管道文件关联的任何缓冲区。如果文件缺失或为空字符串,则刷新所有打开的输出文件和管道。
next 停止处理当前输入记录。读取下一个输入记录并从 AWK 程序的第一个模式开始重新处理。到达输入数据末尾时,执行任何 END 规则。
nextfile 停止处理当前输入文件。读取的下一个输入记录来自下一个输入文件。更新 FILENAME 和 ARGIND,将 FNR 重置为 1,并从 AWK 程序的第一个模式开始重新处理。到达输入数据末尾时,执行任何 ENDFILE 和 END 规则。
print 打印当前记录。输出记录以 ORS 的值为结尾。
print expr-list 打印表达式。每个表达式由 OFS 的值分隔。输出记录以 ORS 的值为结尾。
print expr-list >file 将表达式打印到文件。每个表达式之间用 OFS 的值分隔。输出记录以 ORS 的值结尾。
printf fmt, expr-list 格式化并打印。
printf fmt, expr-list >file
格式化并打印到文件。
system(cmd-line) 执行命令 cmd-line,并返回退出状态。(这可能在非 POSIX 系统上不可用。)请参阅 https://www.gnu.org/software/gawk/manual/html_node/I_002fO-Functions.html#I_002fO-Functions,了解有关退出状态的完整详细信息。
允许对 print 和 printf 进行其他输出重定向。
print ... >> file
将输出附加到文件。
print ... | command
写入管道。
print ... |& command
将数据发送到协进程或套接字。(另请参见下面的“特殊文件名”子部分。)
getline 函数在成功时返回 1,在文件结尾时返回零,在出错时返回 -1。如果 errno(3) 值表明 I/O 操作可以重试,并且 PROCINFO["input", "RETRY"] 已设置,则返回 -2 而不是 -1,并且可以尝试进一步调用 getline。 发生错误时,ERRNO 设置为描述问题的字符串。
注意:打开双向套接字时,会返回一个非致命错误到调用函数。如果使用管道、协进程或套接字来调用 getline,或者从循环内的 print 或 printf 中调用,则必须使用 close() 来创建命令或套接字的新实例。AWK 不会自动在返回 EOF 时关闭管道、套接字或协进程。
AWK 版本的 printf 语句和 sprintf() 函数与 C 类似。 有关详细信息,请参阅 https://www.gnu.org/software/gawk/manual/html_node/Printf.html。
特殊文件名
在从 print 或 printf 重定向到文件,或通过 getline 从文件进行 I/O 时,gawk 内部会识别某些特殊文件名。这些文件名允许访问从 gawk 的父进程(通常是 shell)继承的打开文件描述符。这些文件名也可以在命令行中使用来命名数据文件。文件名如下:
- 标准输入。
/dev/stdin 标准输入。
/dev/stdout 标准输出。
/dev/stderr 标准错误输出。
/dev/fd/n 与打开的文件描述符 n 关联的文件。
以下特殊文件名可与 |& 协进程运算符一起使用,用于创建 TCP/IP 网络连接:
/inet/tcp/lport/rhost/rport
/inet4/tcp/lport/rhost/rport
/inet6/tcp/lport/rhost/rport
用于在本地端口 lport 上到远程主机 rhost 的远程端口 rport 上的 TCP/IP 连接的文件。使用端口 0,让系统选择一个端口。使用 /inet4 强制使用 IPv4 连接,使用 /inet6 强制使用 IPv6 连接。纯 /inet 使用系统默认值(很可能是 IPv4)。只能与 |& 双向 I/O 运算符一起使用。
/inet/udp/lport/rhost/rport
/inet4/udp/lport/rhost/rport
/inet6/udp/lport/rhost/rport
类似,但使用 UDP/IP 而不是 TCP/IP。
数值函数
AWK 具有以下内置算术函数:
atan2(y, x) 返回 y/x 的反正切值,单位为弧度。
cos(expr) 返回 expr 的余弦值,expr 的单位为弧度。
exp(expr) 指数函数。
int(expr) 截断为整数。
log(expr) 自然对数函数。
rand() 返回一个介于零和一之间的随机数 N,满足 0 ≤ N < 1。
sin(expr) 返回 expr 的正弦值,expr 的单位为弧度。
sqrt(expr) 返回 expr 的平方根。
srand([expr]) 使用 expr 作为新的随机数生成器的种子。 如果没有提供 expr,则使用当前时间。 返回随机数生成器的先前种子。
字符串函数
Gawk 具有以下内置字符串函数; 详细信息请参见 [https://www.gnu.org/software/gawk/manual/html_node/String-Functions.html]
asort(s [, d [, how] ]) 返回源数组 s 中的元素数量。 使用 gawk 比较值的标准规则对 s 的内容进行排序,并将排序后的值的索引替换为从 1 开始的连续整数。 如果指定了可选的目标数组 d,则首先将 s 复制到 d,然后对 d 进行排序,同时保持源数组 s 的索引不变。 可选字符串 how 控制排序方向和比较模式。 how 的有效值在 [https://www.gnu.org/software/gawk/manual/html\_node/String-Functions.html\#String-Functions] 中描述。 允许 s 和 d 是同一个数组;只有在提供第三个参数时才有意义。
asorti(s [, d [, how] ])
返回源数组 s 中的元素数量。 其行为与 asort() 相同,不同之处在于使用数组索引进行排序,而不是数组值。 完成后,数组将按数值索引,并且值将是原始索引的值。 原始值将丢失;因此,如果希望保留原始值,请提供第二个数组。 可选字符串 how 的用途与 asort() 相同。 同样,允许 s 和 d 是同一个数组;只有在提供第三个参数时才有意义。
gensub(r, s, h [, t]) 在目标字符串 t 中搜索正则表达式 r 的匹配项。 如果 h 是以 g 或 G 开头的字符串,则将 r 的所有匹配项替换为 s。 否则,h 是一个数字,指示要替换 r 的哪个匹配项。 如果未提供 t,则使用 $0 代替。 在替换文本 s 中,序列 \n(其中 n 是从 1 到 9 的数字)可用于指示仅匹配的第 n 个带括号的子表达式的文本。 序列 \0 表示整个匹配的文本,字符 & 也是如此。 与 sub() 和 gsub() 不同,修改后的字符串作为函数的结果返回,并且原始目标字符串不会更改。
gsub(r, s [, t]) 对于字符串 t 中与正则表达式 r 匹配的每个子字符串,用字符串 s 替换,并返回替换的次数。如果未提供 t,则使用 $0。在替换文本中,& 被替换为实际匹配的文本。使用 \& 来获取字面意义上的 &。 (必须输入 "\\&";有关对 sub()、gsub() 和 gensub() 的替换文本中斜杠和 & 符号的更完整讨论,请参见 https://www.gnu.org/software/gawk/manual/html_node/Gory-Details.html#Gory-Details。)
index(s, t) 返回字符串 s 中字符串 t 的索引,如果 t 不存在,则返回零。(这意味着字符索引从 1 开始。)
length([s]) 返回字符串 s 的长度,或者如果未提供 s,则返回 $0 的长度。对于数组参数,length() 返回数组中的元素数。
match(s, r [, a]) 返回正则表达式 r 在 s 中出现的字符串中的位置,如果 r 不存在,则返回零,并设置 RSTART 和 RLENGTH 的值。请注意,参数顺序与 ~ 运算符的顺序相同:str ~ re。有关如何填充数组 a(如果提供了该数组)的说明,请参见 https://www.gnu.org/software/gawk/manual/html_node/String-Functions.html#String-Functions 。
patsplit(s, a [, r [, seps] ])
将字符串 s 拆分为数组 a 和分隔符数组 seps,使用正则表达式 r 作为分隔符,并返回字段数。元素值是 s 中与 r 匹配的部分。seps[i] 的值是在 a[i] 之后出现的可能的空分隔符。seps[0] 的值是可能的起始空分隔符。如果省略 r,则使用 FPAT。数组 a 和 seps 首先被清除。拆分行为与使用 FPAT 进行的字段拆分完全相同。
split(s, a [, r [, seps] ])
将字符串 s 拆分为数组 a 和分隔符数组 seps,使用正则表达式 r 作为分隔符,并返回字段数。如果省略 r,则使用 FS。数组 a 和 seps 首先被清除。seps[i] 是在 a[i] 和 a[i+1] 之间由 r 匹配的字段分隔符。拆分行为与字段拆分完全相同。
sprintf(fmt, expr-list) 根据 fmt 打印 expr-list,并返回结果字符串。
strtonum(str) 检查 str,并返回其数值。如果 str 以前导 0 开头,则将其视为八进制数。如果 str 以前导 0x 或 0X 开头,则将其视为十六进制数。否则,假定它是一个十进制数。
sub(r, s [, t]) 与 gsub() 类似,但仅替换第一个匹配的子字符串。返回零或一。
substr(s, i [, n]) 返回从 s 的 i 开始的最多 n 个字符的子字符串。如果省略 n,则使用 s 的其余部分。
tolower(str) 返回字符串 str 的副本,其中 str 中的所有大写字符都转换为相应的小写字符。非字母字符保持不变。
toupper(str) 返回字符串 str 的副本,其中 str 中的所有小写字符都转换为相应的大写字符。非字母字符保持不变。
Gawk 支持多字节。这意味着 index()、length()、substr() 和 match() 均以字符为单位进行操作,而非字节。
时间函数
Gawk 提供了以下函数,用于获取时间戳并对其进行格式化。详细信息请参见 https://www.gnu.org/software/gawk/manual/html_node/Time-Functions.
mktime(datespec [, utc-flag])
将 datespec 转换为与 systime() 返回的格式相同的时戳,并返回结果。如果存在 utc-flag 且非零或非空,则假定时间为 UTC 时区;否则,假定时间为本地时区。如果 datespec 不包含足够的元素,或者结果时间超出范围,则 mktime() 返回 -1。有关 datespec 的详细信息,请参见 https://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html#Time-Functions。
strftime([format [, timestamp[, utc-flag]]])
根据 format 中的规范格式化 timestamp。如果存在 utc-flag 且非零或非空,则结果为 UTC,否则结果为本地时间。timestamp 应与 systime() 返回的格式相同。如果缺少 timestamp,则使用当前时间。如果缺少 format,则使用默认格式,该格式等效于 date(1) 的输出。默认格式可在 PROCINFO["strftime"] 中获得。有关 strftime() 函数的规范,请参见 ISO C,以了解保证可用的格式转换。
systime() 返回自 Epoch(POSIX 系统上的 1970-01-01 0000:00 UTC)以来的当前时间(以秒为单位)。
位操作函数
Gawk 提供了以下位操作函数。它们的工作方式是将双精度浮点值转换为 uintmax_t 整数,执行操作,然后将结果转换回浮点值。将负操作数传递给任何这些函数会导致致命错误。
这些函数包括:
and(v1, v2 [, ...]) 返回参数列表中提供的所有值的按位与。必须至少有两个。
compl(val) 返回 val 的按位补。
lshift(val, count) 返回 val 左移 count 位的结果。
or(v1, v2 [, ...]) 返回参数列表中提供的所有值的按位或。必须至少有两个。
rshift(val, count) 返回 val 右移 count 位的结果。
xor(v1, v2 [, ...]) 返回参数列表中提供的所有值的按位异或。必须至少有两个。
类型函数
以下函数提供有关其参数的类型信息。
isarray(x) 如果 x 是数组,则返回 true,否则返回 false。
typeof(x) 返回指示 x 类型的字符串。该字符串将是 "array"、"number"、"regexp"、"string"、"strnum"、"unassigned" 或 "undefined" 中的一种。
国际化函数
以下函数可用于在 AWK 程序中进行运行时字符串翻译。有关完整详细信息,请参阅 https://www.gnu.org/software/gawk/manual/html_node/I18N-Functions.html#I18N-Functions。
bindtextdomain(directory [, domain])
指定 gawk 在其中查找 .gmo 文件的目录,以防这些文件无法或不能放置在“标准”位置。它返回 domain 被“绑定”的目录。默认域是 TEXTDOMAIN 的值。如果 directory 是空字符串 (""),则 bindtextdomain() 返回给定域的当前绑定。
dcgettext(string [, domain [, category]])
返回字符串在文本域 domain 中,对于区域设置类别 category 的翻译。domain 的默认值为当前 TEXTDOMAIN 的值。category 的默认值为 "LC_MESSAGES"。
dcngettext(string1, string2, number [, domain [, category]])
返回用于表示 number 的复数形式的字符串 1 和字符串 2 在文本域 domain 中,对于区域设置类别 category 的翻译。domain 的默认值为当前 TEXTDOMAIN 的值。category 的默认值为 "LC_MESSAGES"。
布尔值函数
您可以创建特殊的布尔型值;请参阅手册以了解其工作原理以及它们存在的原因。
mkbool(expression)
基于表达式的布尔值,返回一个真值或一个假值。真值具有数值 1。假值具有数值 0。
用户定义函数
AWK 中的函数定义如下:
function name(parameter list) { statements }
当从模式或操作中的表达式中调用函数时,函数将被执行。在函数调用中提供的实际参数用于实例化在函数中声明的正式参数。数组按引用传递,其他变量按值传递。
局部变量作为参数列表中额外的参数声明。约定是在参数列表中使用额外的空格将局部变量与实际参数分开。例如:
function f(p, q, a, b) # a 和 b 是局部变量
{
...
}
/abc/ { ... ; f(1, 2) ; ... }
函数调用的左括号必须紧随函数名称之后,中间没有任何空格。此限制不适用于上面列出的内置函数。
函数可以相互调用,并且可以是递归的。用作局部变量的函数参数在函数调用时初始化为空字符串和数字零。
使用 return expr 从函数返回值。如果没有提供值,或者函数通过“到达末尾”的方式返回,则返回值是未定义的。
函数可以间接调用。为此,将要调用的函数名作为字符串赋值给变量。然后将该变量用作函数名,并在其前面加上 @ 符号,如下所示: function myfunc() { print "myfunc called" ... }
{ ...
the_func = "myfunc"
@the_func() # 通过 the_func 调用 myfunc
...
}
如果提供了 --lint 选项,gawk 会在解析时发出警告,提示存在对未定义函数的调用,而不是在运行时发出错误。在运行时调用未定义的函数是一个致命错误。
动态加载新函数
您可以使用 @load 语句将用 C 或 C++ 编写的新函数动态添加到正在运行的 gawk 解释器中。完整的细节超出了本手册页的范围;请参见 https://www.gnu.org/software/gawk/manual/html_node/Dynamic-Extensions.html#Dynamic-Extensions。
信号
gawk 剖析器接受两个信号。SIGUSR1 导致它将剖析信息和函数调用堆栈转储到剖析文件中,该文件是 awkprof.out,或者通过 --profile 选项指定的任何文件。然后它将继续运行。SIGHUP 导致 gawk 转储剖析信息和函数调用堆栈,然后退出。
国际化
字符串常量是包含在双引号中的字符序列。在非英语环境中,可以将 AWK 程序中的字符串标记为需要翻译成本地自然语言。这些字符串在 AWK 程序中以一个前导下划线(“_”)标记。例如,
gawk 'BEGIN { print "hello, world" }'
始终打印 hello, world。但是,
gawk 'BEGIN { print _"hello, world" }'
在法国可能会打印 bonjour, monde。请参见 https://www.gnu.org/software/gawk/manual/html_node/Internationalization.html#Internationalization,了解生成和运行可本地化的 AWK 程序所涉及的步骤。
GNU 扩展
Gawk 具有大量的 POSIX awk 扩展。它们在 https://www.gnu.org/software/gawk/manual/html_node/POSIX_002fGNU.html 中描述。所有扩展都可以通过使用 --traditional 或 --posix 选项调用 gawk 来禁用。
环境变量
AWKPATH 环境变量可用于提供一个目录列表,gawk 在查找通过 -f、--file、-i 和 --include 选项以及 @include 指令命名的文件时会搜索这些目录。如果初始搜索失败,则会附加 .awk 到文件名后再次搜索该路径。
AWKLIBPATH 环境变量可用于提供一个目录列表,gawk 在查找通过 -l 和 --load 选项命名的文件时会搜索这些目录。
如果存在 GAWK_PERSIST_FILE 环境变量,则它指定一个文件,用作持久内存的后端存储。请参见 GAWK:Effective AWK Programming,了解详细信息。
GAWK_READ_TIMEOUT 环境变量可用于指定从终端、管道或双向通信(包括套接字)读取输入的超时时间(以毫秒为单位)。
对于通过套接字连接到远程主机,GAWK_SOCK_RETRIES 控制重试次数,GAWK_MSEC_SLEEP 控制重试之间的间隔,以毫秒为单位。在不支持 usleep(3) 的系统上,该值将向上取整为整数秒。
如果环境变量中存在 POSIXLY_CORRECT,则 gawk 的行为与命令行中指定 --posix 时完全相同。如果已指定 --lint,则 gawk 会为此发出警告消息。
退出状态
如果使用带有值的 exit 语句,则 gawk 将以给定的数值退出。
否则,如果没有在执行过程中出现问题,gawk 将以 C 常量 EXIT_SUCCESS 的值退出。通常,这个值为零。
如果发生错误,gawk 将以 C 常量 EXIT_FAILURE 的值退出。通常,这个值为一。
如果 gawk 因致命错误而退出,则退出状态为 2。在非 POSIX 系统上,该值可能会映射到 EXIT_FAILURE。
版本信息
此手册页记录了 gawk,版本 5.3。
作者
UNIX awk 的原始版本由贝尔实验室的 Alfred Aho、Peter Weinberger 和 Brian Kernighan 设计和实现。Ozan Yigit 是当前的维护者。Brian Kernighan 偶尔也会参与其开发。
Paul Rubin 和 Jay Fenlason,来自自由软件基金会,编写了 gawk,使其与第七版 UNIX 中发布的原始 awk 版本兼容。John Woods 贡献了许多错误修复。David Trueman,并得到 Arnold Robbins 的贡献,使 gawk 与 UNIX awk 的新版本兼容。Arnold Robbins 是当前的维护者。
请参阅《GAWK:有效的 AWK 编程》以获取 gawk 及其文档的完整贡献者列表。
请参阅 gawk 发行版中的 README 文件,以获取有关维护者的最新信息以及当前支持的端口。
错误报告和问题
如果您发现 gawk 中的错误,请使用 gawkbug(1) 程序进行报告。
有关报告错误的完整说明,请参见 https://www.gnu.org/software/gawk/manual/html_node/Bugs.html。请仔细阅读并遵循给定的说明。这将使每个人都能更轻松地报告和解决错误。真的。
另一方面,如果您有关于如何使用 awk 或 gawk 完成特定任务的问题,请发送电子邮件到 _,并提出您的请求。
错误
^ F 选项对于考虑到命令行变量赋值功能来说是不必要的;它仅保留是为了向后兼容。
此手册页太长;gawk 有太多功能。
参见
^ grep(1)、sed(1)、gawkbug(1)、printf(3) 和 strftime(3)。
《AWK 编程语言》,第二版,Alfred V. Aho、Brian W. Kernighan、Peter J. Weinberger,Addison-Wesley,2023。ISBN 9-780138-269722。
《GAWK:有效的 AWK 编程》,第五版,与 gawk 源代码一起发布。当前版本的文档可在 https://www.gnu.org/software/gawk/manual 在线获取。
GNU gettext 文档,可在 https://www.gnu.org/software/gettext 上在线获取。
示例
打印并排序所有用户的登录名:
BEGIN { FS = ":" }
{ print $1 | "sort" }
计算文件中的行数:
{ nlines++ }
END { print nlines }
在每行前面加上它在文件中的编号:
{ print FNR, $0 }
连接并加上行号(主题的变体):
{ print NR, $0 }
针对数据中的特定行运行外部命令:
tail -f access_log |
awk '/myhome.html/ { system("nmap " $1 ">> logdir/myhome.html") }'
复制权限
版权所有 © 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005 2007, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 2024, 2025 Free Software Foundation, Inc.
允许制作和分发此手册页的逐字副本,前提是所有副本上都保留版权声明和此权限声明。
允许在遵循逐字复制条件的条件下,复制和分发此手册页的修改版本,前提是整个生成的衍生作品都以与此相同的权限声明的形式分发。
允许将此手册页翻译成另一种语言,并遵循上述修改版本的条件,但此权限声明可以用基金会批准的翻译形式声明。