Awk

POSIX awk 對變數/printf 中的空字節的立場是什麼?

  • January 27, 2020

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 的實現。

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