POSIX awk 对变量/printf 中的空字节的立场是什么?

gra*_*olf 12 standard awk posix

printf根据 POSIX使用 awk 的函数打印空字节是否合法?该的POSIX标准awk似乎并没有明确提到这两种方式。现实世界的实现在行为方式上有所不同:

+$ gawk 'BEGIN { x = sprintf("\000"); print(length(x)); }'
1
+$ busybox awk 'BEGIN { x = sprintf("\000"); print(length(x)); }'
0
+$
Run Code Online (Sandbox Code Playgroud)

+$ gawk 'BEGIN { printf("\000"); }' | xxd
00000000: 00                                       .
+$ busybox awk 'BEGIN { printf("\000"); }' | xxd
+$
Run Code Online (Sandbox Code Playgroud)

这是在标准中的某处指定的吗?如果是,变量 ( x = sprintf("\000")) 和 printf ( printf("\000"))所需的行为是否相同?

Sté*_*las 18

POSIX.2018 规范中awk至少有 4 段相关文本:

在下面所有引用的文本中,重点(粗体文本)是我的:

来自以下任何来源的 awk 程序的输入文件应为文本文件

这意味着如果输入包含 NUL 字符(根据文本的 POSIX 定义,这将使其成为非文本),则行为未指定。

\ddd :一个 <反斜杠> 字符,后跟一个、两个或三个八进制数字字符的最长序列 (01234567)。 如果所有数字都是 0(即 NUL 字符的表示),则行为是 undefined

因此\000导致未定义的行为。

关于正则表达式匹配:

但是,在所有 awk ERE 匹配中,在模式、输入记录或文本字符串中使用一个或多个 NUL 字符会产生未定义的结果

关于printf/ sprintf:

7. 对于c 转换说明符字符:如果参数为数值,则输出编码为该值的字符。如果该值为零或不是字符集中任何字符的编码,则行为是 undefined

因此,这是获取导致未定义行为的 NUL 字符的另一种方法。

因此,总而言之,在awkPOSIX中,您不能使用可移植的 NUL 字符,无论是用于输入、输出还是存储在其变量中。

gawk(至少从 1989 年的 2.10 开始,这是我可以找到记录NUL 支持的最早版本)和@ThomasDickeymawk(自20140914 版以来)是两个可以处理 NUL 的实现。