Awk
POSIX awk 對變數/printf 中的空字節的立場是什麼?
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 條相關文本:在下面所有引用的文本中,重點(粗體文本)是我的:
來自以下任何來源的 awk 程序的輸入文件應為文本文件
這意味著如果輸入包含 NUL 字元(根據 POSIX 文本定義,這將使其成為非文本),那麼行為是未指定的。
\ddd :一個 <反斜杠> 字元,後跟一個、兩個或三個八進制數字字元的最長序列 (01234567)。 如果所有數字都是 0(即 NUL 字元的表示),則行為是 undefined。
因此
\000
導致未定義的行為。關於正則表達式匹配:
但是,在所有 awk ERE 匹配中,在模式、輸入記錄或文本字元串中使用一個或多個 NUL 字元會產生未定義的結果
關於
printf
/sprintf
:7.對於c轉換說明符字元:如果參數有數值,則輸出編碼為該數值的字元。如果該值為零或不是字元集中任何字元的編碼,則行為未定義。
所以,這是另一種獲得導致未定義行為的 NUL 字元的方法。
所以,總而言之,在 中
awk
,POSIX 告訴我們你不能以可移植的方式使用 NUL 字元,無論是用於輸入、輸出還是儲存在其變數中。
gawk
(至少從 1989 年的 2.10 開始,這是我能找到的記錄 NUL 支持的最早版本)和@ThomasDickeymawk
(從版本 20140914 開始)是兩個可以處理 NUL 的實現。