搭建好网站如何使用蜜桃传播18媒体免费观看
1 第5.1节:awk内置变量
1.1 控制型变量
以下是按字母顺序排列的变量列表,你可通过修改这些变量来控制 awk 执行某些操作的方式。
特定于 gawk 的变量会标记有井号(# )。这些变量属于 gawk 的扩展特性。在其他 awk 实现中,或者当 gawk 处于兼容模式时,它们不会有特殊作用(每个变量的描述中会注明任何例外情况 )。
1.1.1 BINMODE
在非 POSIX 系统上,此变量指定对所有 I/O 使用二进制模式。数值为 1、2 或 3 时,分别表示输入文件、输出文件或所有文件应使用二进制 I/O 。数值小于 0 会被视为 0 ,数值大于 3 会被视为 3 。另外,字符串值 "r" 或 "w" 分别表示输入文件和输出文件应使用二进制 I/O 。字符串值 "rw" 或 "wr" 表示所有文件都应使用二进制 I/O 。任何其他字符串值会被当作 "rw" 处理,但会导致 gawk 生成一条警告消息。mawk也支持此变量,但仅支持使用数值。
1.1.2 CONVFMT
一个用于控制数字转换为字符串的规则的字符串,其工作方式实际上是,作为第一个参数传递给 sprintf() 函数。它的默认值是 "%.6g" 。CONVFMT 是由 POSIX 标准引入的。
1.1.3 FIELDWIDTHS
由空格分隔的列宽度列表,告知gawk如何按固定列边界拆分输入。从版本4.2开始,每个字段宽度前可选择性地加上由冒号分隔的值,用于指定字段开始前要跳过的字符数。为FIELDWIDTHS赋值会覆盖FS和FPAT在字段拆分方面的作用 。
1.1.4 FPAT
一个正则表达式(以字符串形式),告知gawk根据匹配该正则表达式的文本来创建字段。为FPAT赋值会覆盖FS和FIELDWIDTHS在字段拆分方面的作用。
1.1.5 FS
输入字段分隔符。其值可以是单字符字符串,也可以是多字符正则表达式,用于匹配记录中字段间的分隔符。若值为空字符串("" ),则记录中的每个字符都会成为单独的字段(此行为是gawk的扩展特性,POSIX awk未规定FS为空字符串时的行为。不过,其他一些awk版本也会特殊处理"" )。
默认值是 " " ,即由单个空格组成的字符串。作为特殊例外,此值意味着任意空格、制表符和/或换行符序列都算作一个分隔符,且记录开头和结尾的空格、制表符及换行符会被忽略。
你可通过命令行的-F选项设置FS的值,例如:
awk -F, 'program' input-files
若gawk正使用FIELDWIDTHS或FPAT进行字段拆分,为FS赋值会让gawk恢复为基于FS的常规字段拆分方式。简单执行FS = FS(可附带解释性注释 )就能轻松实现这一点。
1.1.6 IGNORECASE
若IGNORECASE为非零值或非空值,那么所有字符串比较以及所有正则表达式匹配都会不区分大小写。这适用于正则表达式匹配操作符~和!~、gensub()、gsub()、index()、match()、patsplit()、split()以及sub()函数,也适用于记录终止符RS的匹配,还有基于FS和FPAT的字段拆分。不过,IGNORECASE的值不会影响数组下标,也不会影响使用单字符字段分隔符时的字段拆分。
1.1.7 LINT
当此变量为真(非零或非空)时,gawk的行为等同于启用--lint命令行选项(。若值为"fatal",lint警告会变为致命错误;若值为"invalid",仅会发出关于实际无效内容的警告(此功能尚未完全实现 )。任何为真的值都会打印非致命警告。为LINT赋假值会关闭lint警告。
此变量是gawk的扩展特性,在其他awk实现中无特殊作用。与其他特殊变量不同,即便gawk处于兼容模式,修改LINT也会影响lint警告的产生,就像 --lint 和 --traditional 选项可独立控制 gawk 行为的不同方面一样,程序执行期间对 lint 警告的控制,与正在运行的 awk 实现风格无关 。
(说明:--lint 用于开启代码检查类警告,--traditional 让 gawk 兼容传统 awk 行为;“flavor of awk” 意译为 “awk 实现风格” ,体现不同 awk 变体的特性 )
1.1.8 OFMT
控制使用 print 语句打印时,数字转换为字符串的格式。其工作方式是作为第一个参数传递给 sprintf() 函数。它的默认值是 "%.6g" 。早期版本的 awk 用 OFMT 指定一般表达式中数字转字符串的格式;现在这项功能由 CONVFMT 实现 。
1.1.9 OFS
输出字段分隔符。print 语句输出时,会在字段之间插入该分隔符。它的默认值是 " " ,即由单个空格组成的字符串 。
1.1.10 ORS
输出记录分隔符。每个 print 语句执行结束时会输出它。默认值是 "\n" ,即换行符 。
1.1.11 PREC
任意精度浮点数运算时使用的工作精度,默认是 53 位 。
1.1.12 ROUNDMODE
用于任意精度算术运算的舍入模式,默认是 "N"(对应 IEEE 754 标准中的 roundTiesToEven;
1.1.13 RS
输入记录分隔符。默认值是包含单个换行符的字符串,这意味着一个输入记录就是文本中的一行。它也可以是空字符串,此时记录由连续的空行分隔。若它是正则表达式,记录则由匹配该正则表达式的输入文本分隔。RS 支持正则表达式是 gawk 的扩展特性。在大多数其他 awk 实现中,或者当 gawk 处于兼容模式时,只会使用 RS 值的第一个字符 。
1.1.14 SUBSEP
下标分隔符。默认值是 "\034" ,用于分隔多维数组下标的各部分。因此,表达式 foo["A", "B"] 实际访问的是 foo["A\034B"] 。
1.1.15 TEXTDOMAIN
用于在 awk 层面实现程序的国际化。它为源代码中经过特殊标记的字符串常量设置默认文本域,也用于 dcgettext()、dngettext() 和 bindtextdomain() 函数(。TEXTDOMAIN 的默认值是 "messages" 。
1.2 用于传递信息的内置变量
以下是按字母顺序排列的变量列表,awk 会在特定情况下自动设置这些变量,以便向你的程序传递信息。
特定于 gawk 的变量会用井号(# )标记。这些变量是 gawk 的扩展特性。在其他 awk 实现中,或者当 gawk 处于兼容模式时,它们不会有特殊含义:
1.2.1 ARGC、ARGV
awk 程序可用的命令行参数存储在一个名为 ARGV 的数组中。ARGC 是命令行参数的数量。与大多数 awk 数组不同,ARGV 的索引从 0 到 ARGC - 1 。看以下示例:
$ awk 'BEGIN {for (i = 0; i < ARGC; i++)print ARGV[i]}' inventory-shipped mail-list
-| awk
-| inventory-shipped
-| mail-list
ARGV[0] 包含 awk ,ARGV[1] 包含 inventory-shipped ,ARGV[2] 包含 mail-list 。ARGC 的值是 3 ,比 ARGV 最后一个元素的索引大 1 ,因为元素是从 0 开始编号的。
ARGC 和 ARGV 的命名,以及数组索引从 0 到 ARGC - 1 的惯例,源自 C 语言访问命令行参数的方式。
ARGV[0] 的值在不同系统上可能不同。另外要注意,程序文本不会包含在 ARGV 中,awk 的任何命令行选项也不会。想了解 awk 如何使用这些变量 。
1.2.2 ARGIND
当前正在处理文件在 ARGV 中的索引。每当 gawk 打开一个新数据文件进行处理时,会将 ARGIND 设置为该文件名在 ARGV 中的索引。当 gawk 处理输入文件时,FILENAME == ARGV[ARGIND] 始终为真。
此变量在文件处理中很有用:它能让你知晓在数据文件列表中处理到了什么位置,还能区分命令行上连续出现的同名文件实例。
虽然你可在 awk 程序中修改 ARGIND 的值,但 gawk 打开下一个文件时,会自动将其设为新值。
1.2.3 ENVIRON
一个关联数组,包含环境变量的值;数组索引是环境变量的名称,元素是对应环境变量的值。例如,ENVIRON["HOME"] 的值可能是 /home/arnold 。
对于 POSIX awk ,修改此数组不会影响传递给 awk 衍生出的程序的环境(通过重定向或 system() 函数 )。不过,从版本 4.2 开始,若 gawk 处于非 POSIX 兼容模式,修改 ENVIRON 时,gawk 会更新自身环境,进而改变它创建的程序所看到的环境。因此,你若在 gawk 中修改 ENVIRON ,要留意对后续衍生程序环境的影响。因此,如果你修改 ENVIRON["PATH"] 时应格外小心,因为它是查找可执行程序的搜索路径。
这也可能会影响正在运行的 gawk 程序,因为某些内置函数可能会关注特定的环境变量。最显著的例子是 mktime(),在许多系统上,它会关注 TZ 环境变量的值。
有些操作系统可能没有环境变量。在这类系统上,ENVIRON 数组是空的(ENVIRON["AWKPATH"] 和 ENVIRON["AWKLIBPATH"] 除外。
1.2.4 ERRNO
若在为 getline 进行重定向期间、getline 读取期间,或者 close() 操作期间发生系统错误,ERRNO 会包含一个描述该错误的字符串。
此外,gawk 在打开每个命令行输入文件前,会清空 ERRNO 。这使得可以在 BEGINFILE 模式中检查文件是否可读。
除此之外,ERRNO 的工作方式类似于 C 语言的 errno 变量。除了刚提到的情况,gawk 从不会清空它(设为 0 或空字符串 "" )。因此,只有当 I/O 操作返回失败值(比如 getline 返回 -1 )时,你才应期望它的值有意义。当然,你完全可以在执行 I/O 操作前自行清空它。
若 ERRNO 的值对应 C 语言 errno 变量中的系统错误,PROCINFO["errno"] 会被设为 errno 的值。对于非系统错误,PROCINFO["errno"] 会是 0 。
1.2.5 FILENAME
当前输入文件的名称。当命令行上未列出数据文件时,awk 从标准输入读取,此时 FILENAME 被设为 "-" 。
每次读取新文件时,FILENAME 会改变。在 BEGIN 规则中,FILENAME 的值是空字符串 "" ,因为此时还未处理任何输入文件。不过要注意,在 BEGIN 规则中使用 getline,可能会为 FILENAME 赋予一个值。
1.2.6 FNR
当前文件中的当前记录号。awk 每次读取一条新记录时,会递增 FNR。
awk 每次开始处理一个新输入文件时,会将 FNR 重置为 0 。
1.2.7 NF
当前输入记录的字段数量。每当读取一条新记录、创建一个新字段,或者 $0 发生变化时,NF 会被设置。
与本小节描述的大多数变量不同,为 NF 赋值有可能影响 awk 的内部运作。具体而言,对 NF 赋值可用于在当前记录中创建字段或删除字段。
1.2.8 PROCINFO
该数组的元素可用于获取关于正在运行的 awk 程序的信息。以下元素(按字母顺序列出 )保证可用:
1.2.8.1 PROCINFO[“argv”]
PROCINFO["argv"] 数组包含所有命令行参数(在支持通配符扩展和重定向处理的平台上,这些处理是程序需手动完成的 ),下标范围从 0 到 argc - 1 。例如,PROCINFO["argv"][0] 会包含调用 gawk 时所用的名称。以下是一个说明该特性用法的示例:
gawk '
BEGIN {for (i = 0; i < length(PROCINFO["argv"]); i++)print i, PROCINFO["argv"][i]
}'
请注意,这与标准 ARGV 数组不同,标准 ARGV 数组不包含已被 gawk 处理过的命令行参数。
1.2.8.2 PROCINFO[“egid”]
getegid() 系统调用的返回值。
1.2.8.3 PROCINFO[“errno”]
当 ERRNO 被设为相关错误消息时,C 语言 errno 变量的值。
1.2.8.4 PROCINFO[“euid”]
geteuid() 系统调用的返回值。
1.2.8.5 PROCINFO[“FS”]
若当前是用 FS 进行字段拆分,值为 "FS" ;若用 FIELDWIDTHS 进行字段拆分,值为 "FIELDWIDTHS" ;若用 FPAT 进行字段匹配拆分,值为 "FPAT" ;若字段拆分由 API 输入解析器控制,值为 "API" 。
1.2.9 PROCINFO[“gid”]
getgid() 系统调用的返回值。
1.2.10 PROCINFO[“identifiers”]
一个子数组,下标为 awk 程序文本中使用的所有标识符名称。标识符指的是变量(无论是标量还是数组 )、内置函数、用户定义函数或扩展函数的名称。对于每个标识符,该元素的值为以下之一:
"array":标识符是数组。"builtin":标识符是内置函数。"extension":标识符是通过@load或-l加载的扩展函数。"scalar":标识符是标量。"untyped":标识符无类型(可作为标量或数组使用;gawk尚未确定其类型 )。"user":标识符是用户定义函数。
这些值表示 gawk 解析完程序后对标识符的认知;程序运行期间不会更新。
1.2.10.1 PROCINFO[“platform”]
此元素提供一个字符串,表明 gawk 编译所针对的平台。其值为以下之一:
"mingw":Microsoft Windows,使用 MinGW 编译。"os390":OS/390(也称为 z/OS )。"posix":GNU/Linux、Cygwin、macOS 以及传统类 Unix 系统。"vms":OpenVMS。
1.2.10.2 PROCINFO[“pgrpid”]
当前进程的进程组 ID 。
1.2.10.3 PROCINFO[“pid”]
当前进程的进程 ID 。
1.2.10.4 PROCINFO[“pma”]
编译到 gawk 中的 PMA 内存分配器的版本。若 PMA 分配器不可用,此元素不存在。
1.2.10.5 PROCINFO[“ppid”]
当前进程的父进程 ID 。
1.2.10.6 PROCINFO[“strftime”]
strftime() 函数的默认时间格式字符串。为此元素赋值会改变默认格式。
1.2.10.7 PROCINFO[“uid”]
getuid() 系统调用的返回值。
1.2.10.8 PROCINFO[“version”]
gawk 的版本。
以下额外数组元素可在你的 gawk 版本支持任意精度算术运算时,提供关于 MPFR 和 GMP 库的信息:
1.2.10.9 PROCINFO[“gmp_version”]
GNU MP 库的版本。
1.2.10.10 PROCINFO[“mpfr_version”]
GNU MPFR 库的版本。
1.2.10.11 PROCINFO[“prec_max”]
MPFR 支持的最大精度。
1.2.10.12 PROCINFO[“prec_min”]
MPFR 要求的最小精度。
以下额外数组元素可在你的 gawk 版本支持动态加载扩展函数时,提供关于扩展 API 版本的信息:
1.2.10.13 PROCINFO[“api_major”]
扩展 API 的主版本号。
1.2.10.14 PROCINFO[“api_minor”]
扩展 API 的次版本号。
在部分系统中,数组里可能有 "group1" 到 "groupN"(N 为某个数 )形式的元素。N 是进程所属补充组的数量。可使用 in 运算符测试这些元素是否存在。
以下元素可用于改变 gawk 的行为:
1.2.10.15 PROCINFO[“BUFFERPIPE”]
若此元素存在,所有输出到管道的内容会被缓冲。
1.2.10.16 PROCINFO[“command”, “BUFFERPIPE”]
使输出到指定命令的内容被缓冲。
1.2.10.17 PROCINFO[“NONFATAL”]
若此元素存在,所有重定向操作的 I/O 错误会变为非致命错误。
1.2.10.18 PROCINFO[“name”, “NONFATAL”]
使针对 name 的 I/O 错误变为非致命错误。
1.2.10.19 PROCINFO[“command”, “pty”]
若要与 command 进行双向通信,使用伪终端(pseudo-tty )而非建立双向管道。
1.2.10.20 PROCINFO[“input_name”, “READ_TIMEOUT”]
为从输入重定向 input_name 读取数据设置超时时间。
1.2.10.21 PROCINFO[“input_name”, “RETRY”]
从 input_name 读取数据时,若发生可重试的 I/O 错误,且此数组项存在,getline 会返回 -2 ,而非默认返回 -1 并将 input_name 配置为不再返回数据。当 errno 值为 EAGAIN、EWOULDBLOCK、EINTR 或 ETIMEDOUT 时,I/O 错误可重试。此特性与 PROCINFO["input_name", "READ_TIMEOUT"] 配合使用,或在文件描述符被配置为非阻塞模式的场景中可能有用。
1.2.10.22 PROCINFO[“sorted_in”]
若 PROCINFO 中存在此元素,其值会控制 for (indx in array) 循环处理数组下标的顺序。这是一项高级特性,完整说明将延后;
1.2.11 RLENGTH
由 match() 函数匹配到的子字符串长度。调用 match() 函数会设置 RLENGTH ,其值为匹配字符串的长度,若未找到匹配则为 -1 。
1.2.12 RSTART
match() 函数匹配到的子字符串的起始字符索引。调用 match() 函数会设置 RSTART ,其值为字符串中匹配子字符串的起始位置,若未找到匹配则为 0 。
1.2.13 RT
每次读取一条记录时,若文本匹配记录分隔符 RS 指定的内容,RT 会被设置为该匹配文本。
1.2.14 SYMTAB
一个数组,其下标为程序中所有已定义的全局变量和数组的名称。SYMTAB 让 gawk 的符号表对 awk 程序员可见。gawk 解析程序时构建该数组,程序开始运行前就已完整。
此数组可用于间接访问变量的值(读或写 ):
foo = 5SYMTAB["foo"] = 4
print foo # 输出 4
isarray() 函数可用于测试 SYMTAB 中的元素是否为数组。另外,不能对 SYMTAB 数组使用 delete 语句。
在 gawk 5.0 版本之前,你可以对 SYMTAB 使用未预定义的下标,例如:
SYMTAB["xxx"] = 5
print SYMTAB["xxx"]
但这种用法现已失效,会产生致命错误,因为它曾导致严重混乱。
SYMTAB 数组比表面看起来更有意思。Andrew Schorr 指出,它实际上为 awk 提供了“数据指针”功能。看他的示例:
# 通过间接方式将任意变量乘以指定数值并返回结果
function multiply(variable, amount)
{return SYMTAB[variable] *= amount
}# 使用示例
BEGIN {answer = 10.5multiply("answer", 4)print "The answer is", answer
}
运行结果:
$ gawk -f answer.awk
The answer is 42
注意:为避免严重的“时间旅行悖论”,FUNCTAB 和 SYMTAB 都不能作为 SYMTAB 数组的元素。
1.2.15 关于 NR 和 FNR 的修改
awk 每次读取一条新记录时,会递增 NR 和 FNR ,而非将它们设为已读记录数量的绝对值。这意味着程序可修改这些变量,且后续每条记录读取时,新值会继续递增。以下示例展示了这一点:
$ echo '1'
> 2
> 3
> 4' | awk 'NR == 2 { NR = 17 }
> { print NR }'
-| 1
-| 17
-| 18
-| 19
在 FNR 被加入 awk 语言之前,许多 awk 程序利用此特性,在 FILENAME 改变时将 NR 重置为 0 ,以此跟踪文件中的记录数量。
1.2.16 使用 ARGC 和 ARGV
以下代码打印出包含在 ARGC 和 ARGV 中的信息:
$ awk 'BEGIN {for (i = 0; i < ARGC; i++)print ARGV[i]}' inventory-shipped mail-list
-| awk
-| inventory-shipped
-| mail-list
在此示例中,ARGV[0] 包含 awk ,ARGV[1] 包含 inventory-shipped ,ARGV[2] 包含 mail-list 。注意,awk 程序本身不会加入 ARGV 。其他命令行选项及其参数也不会加入,包括用 -v 选项进行的变量赋值。命令行上的常规变量赋值会被当作参数,显示在 ARGV 数组中。假设有一个名为 showargs.awk 的文件,内容如下:
BEGIN {printf "A=%d, B=%d\n", A, Bfor (i = 0; i < ARGC; i++)printf "\tARGV[%d] = %s\n", i, ARGV[i]
}
END { printf "A=%d, B=%d\n", A, B }
运行它会产生如下结果:
$ awk -v A=1 -f showargs.awk B=2 /dev/null
-| A=1, B=0-| ARGV[0] = awk
-| ARGV[1] = B=2
-| ARGV[2] = /dev/null
-| A=1, B=2
程序可修改 ARGC 和 ARGV 的元素。每当 awk 处理完一个输入文件,会使用 ARGV 的下一个元素作为下一个输入文件的名称。通过在 ARGV 中存储不同字符串,程序可改变要读取的文件。用 "-" 表示标准输入。存储额外元素并递增 ARGC 会使更多文件被读取。
若减小 ARGC 的值,会从列表末尾移除输入文件。程序可将 ARGC 的旧值记录到其他地方,把被移除的参数当作非文件名的内容处理。
要从列表中间移除文件,可在 ARGV 中对应文件名称的位置存入空字符串("" )。作为特殊特性,awk 会忽略被替换为空字符串的文件名。另一种方式是使用 delete 语句从 ARGV 中移除元素
所有这些操作通常在 BEGIN 规则中完成,即在实际处理输入开始前。了解从 ARGV 移除元素的不同方式示例。
要真正把选项传入 awk 程序,需用 -- 结束 awk 选项,然后在后续提供 awk 程序的选项,如下:
awk -f myprog.awk -- -v -q file1 file2 ...
以下代码片段会处理 ARGV ,检查并移除前面提到的命令行选项:
BEGIN {for (i = 1; i < ARGC; i++) {if (ARGV[i] == "-v")verbose = 1else if (ARGV[i] == "-q")debug = 1else if (ARGV[i] ~ /^-./) {e = sprintf("%s: unrecognized option -- %c",ARGV[0], substr(ARGV[i], 2, 1))print e > "/dev/stderr"} elsebreakdelete ARGV[i]}
}
在 gawk 中,用 -- 结束 awk 选项并非必需。除非指定了 --posix ,否则 gawk 会悄悄将任何无法识别的选项放入 ARGV ,供 awk 程序处理。一旦遇到未知选项,gawk 会停止查找其他可能识别的选项。前面带 gawk 的命令行示例如下:
gawk -f myprog.awk -q -v file1 file2 ...
因为 -q 不是有效的 gawk 选项,它和后面的 -v 会被传递给 awk 程序
设计程序时,应选择不会与 gawk 冲突的选项,因为 gawk 会先处理它能识别的选项,再将剩余命令行内容传递给你的程序。结合 -E 选项使用 #! 可能会有帮助
作者声明:本文用于记录和分享作者的学习心得,可能有部分文字或示例来自AI平台,如:豆包、DeepSeek(硅基流动)(注册链接)等,由于本人水平有限,难免存在表达错误,欢迎留言交流和指教!
Copyright © 2022~2025 All rights reserved.
