我在 Gawk 手册中读到了这个:
GNU 扩展
[...]
使用空字符串作为 FS 的值并作为 split() 的第三个参数来拆分单个字符的能力。
然而,情况似乎并非如此。这按预期工作:
$ gawk 'BEGIN {print split("quebec", z, "")}'
6
我可以禁用其他扩展:
$ export POSIXLY_CORRECT
$ gawk 'BEGIN {typeof(1)}'
gawk: cmd. line:1: fatal: function `typeof' not defined
但我不能禁用拆分行为:
$ export POSIXLY_CORRECT
$ gawk 'BEGIN {print split("quebec", z, "")}'
6
$ gawk --posix 'BEGIN {print split("quebec", z, "")}'
6
我还看了 Mawk 手册:
如果 FS = "",则 mawk 将记录拆分为单个字符,并且类似地,split(s,A,"") 将 s 的单个字符放入 A。
[...]
Posix 明确地未定义 FS = "" 的行为,并提到将记录拆分为字符作为一种可能的解释,但目前这种用法不能跨实现移植。
那么,用什么实现你不能用FS
and
得到单个字符split
?
这不是 POSIX,因为您不能在 POSIX 脚本中使用它,因为 POSIX 保留了未指定的行为。这意味着虽然应用程序(脚本)如果想要可移植就不能使用它,但实现(
awk
实现)可以做它想做的任何事情,如果你这样做并且仍然是 POSIX。POSIX 不需要awk
拆分为字符或字节,或者报告错误,或者重新启动计算机,它没有指定。因此,在环境
gawk
中时没有理由改变其在这方面$POSIXLY_CORRECT
的行为¹,在这种情况下,没有比其他行为更正确的行为。正如您所发现的,该扩展名存在于 gawk(自 3.0,1996 年 1 月)和 mawk(自 1.2 版,1996 年 1 月)中。它也在busybox 中
awk
(从一开始(2002 年)),并且自1996 年5 月以来也在Brian Kernighan 维护的那个中(k
inawk
)(FIXES
文件参考gawk
等作为灵感)。看起来它在几个月内被添加到所有 3 个中,这表明它可能在他们的维护者之间进行了讨论。我现在不太确定是谁先想到的。使用 Brian Kernighan 的
awk
或基于 FreeBSD 或 OpenBSD 的那些,请注意,虽然FS
传递给的空或空的第三个参数split()
会导致字符串被拆分为单独的字符(嗯,bytes,见下文),但awk -F ''
返回错误(awk -v FS=
不过没关系)。在 Solaris 上,
nawk
和/usr/xpg4/bin/awk
(以及/bin/awk
70 年代的旧版本),一个空的FS
似乎完全禁用拆分。nawk -F ''
返回错误。我希望它在其他基于 AT&T 代码(如 AIX 或 HP/UX)的商业 Unices 上是相同的,尽管我无法在那里进行测试。另请注意
mawk
,bwk (基于awk
它的某些人不同)和busybox awk 不支持多字节字符。例如,在 UTF-8 中:将以我的名字打印第三个字符的后半部分。因此,有了这些,更正确的说法是空的 FS 拆分为单个字节,而不是字符。
¹我现在意识到,使用 POSIXLY_CORRECT, or
--posix
会gawk
禁用一些不与 POSIX 冲突的扩展(typeof
虽然确实gawk
不符合),所以你可以说这是一个遗漏。现在它不会是第一个。例如,nextfile
即使它确实与 POSIX 冲突,它也不会禁用(awk '{nextfile = 1}'
意味着将 1 分配给变量,但即使在 POSIXLY_CORRECT 下也会nextfile
报告错误)。gawk