printf
根据 POSIX使用 awk 的函数打印空字节是否合法?无论哪种方式,POSIX 标准awk
似乎都没有明确提及。现实世界的实现在行为方式上有所不同:
+$ gawk 'BEGIN { x = sprintf("\000"); print(length(x)); }'
1
+$ busybox awk 'BEGIN { x = sprintf("\000"); print(length(x)); }'
0
+$
和
+$ gawk 'BEGIN { printf("\000"); }' | xxd
00000000: 00 .
+$ busybox awk 'BEGIN { printf("\000"); }' | xxd
+$
这是在标准中的某处指定的吗?x = sprintf("\000")
如果是,变量 ( ) 和 printf ( )所需的行为是否printf("\000")
相同?
POSIX.2018 规范中
awk
至少有 4 条相关文本:在下面所有引用的文本中,重点(粗体文本)是我的:
这意味着如果输入包含 NUL 字符(根据 POSIX 文本定义,这将使其成为非文本),那么行为是未指定的。
因此
\000
导致未定义的行为。关于正则表达式匹配:
关于
printf
/sprintf
:所以,这是另一种获得导致未定义行为的 NUL 字符的方法。
所以,总而言之,在 中
awk
,POSIX 告诉我们你不能以可移植的方式使用 NUL 字符,无论是用于输入、输出还是存储在其变量中。gawk
(至少从 1989 年的 2.10 开始,这是我能找到的记录 NUL 支持的最早版本)和@ThomasDickeymawk
(从版本 20140914 开始)是两个可以处理 NUL 的实现。C 字符串通常不能包含 nul 字节,
awk
基本上是某种 C 解释器。POSIX 标准中需要明确提及能够打印 nul 字节的 POSIX 实用程序。printf
在awk
不是这样的情况下。POSIX 中明确列出了以下情况:
所有三个命令都在带有 POSIX UNIX 品牌的经过认证的操作系统上打印四个字符。
您的
awk
示例正在使用未指定的行为。