使用空字元串拆分單個字元
我在 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 中:echo Stéphane | awk -v FS= '{print $4}'
將以我的名字列印第三個字元的後半部分。因此,有了這些,更正確的說法是空的 FS 拆分為單個字節,而不是字元。
¹我現在意識到使用 POSIXLY_CORRECT, or
--posix
會gawk
禁用一些不與 POSIX 衝突的擴展(typeof
雖然確實gawk
不符合),所以你可以說這是一個遺漏。現在它不會是第一個。例如,nextfile
即使它確實與 POSIX 衝突,它也不會禁用(awk '{nextfile = 1}'
意味著將 1 分配給變數,但即使在 POSIXLY_CORRECT 下也會nextfile
報告錯誤)。gawk