Awk

使用空字元串拆分單個字元

  • March 22, 2018

我在 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 = "" 的行為,並提到將記錄拆分為字元作為一種可能的解釋,但目前這種用法不能跨實現移植。

那麼,用什麼實現你不能用FSand 得到單個字元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 維護的那個中(kin awk)(FIXES文件引用*gawk等*作為靈感)。看起來它在幾個月內被添加到所有 3 個中,這表明它可能在他們的維護者之間進行了討論。我現在不太確定是誰先想到的。

使用 Brian Kernighan 的awk或基於 FreeBSD 或 OpenBSD 的那些,請注意,雖然FS傳遞給的空或空的第三個參數split()會導致字元串被拆分為單獨的字元(嗯,bytes,見下文),但awk -F ''返回錯誤(awk -v FS=不過沒關係)。

在 Solaris 上,nawk/usr/xpg4/bin/awk(以及/bin/awk70 年代的舊版本),一個空的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--posixgawk禁用一些不與 POSIX 衝突的擴展(typeof雖然確實gawk不符合),所以你可以說這是一個遺漏。現在它不會是第一個。例如,nextfile即使它確實與 POSIX 衝突,它也不會禁用(awk '{nextfile = 1}'意味著將 1 分配給變數,但即使在 POSIXLY_CORRECT 下也會nextfile報告錯誤)。gawk

引用自:https://unix.stackexchange.com/questions/417105