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")
Variable()とprintf()に必要な動作はprintf("\000")
同じですか?
答え1
関連テキストが4つ以上あります。POSIX.2018仕様awk
:
以下に引用されたすべてのテキストで強調(太字)は私がしたことです。
次のいずれかのソースのawkプログラムの入力ファイルは、次のようになります。テキスト文書
これは、入力にNUL文字が含まれている場合(POSIXテキスト定義に従ってテキストではない場合)、アクションが指定されていないことを意味します。
\ddd : <バックスラッシュ> 文字の後に、1、2、または 3 つの 8 進文字で構成される最も長い順序が続きます (01234567)。 すべての数値が0(つまり、NUL文字表現)の場合、動作は未定義です。。
これ\000
により、未定義の動作が発生します。
正規表現マッチング関連:
しかし、すべてのawk EREゲームではパターン、入力レコード、またはテキスト文字列に 1 つ以上の NUL 文字を使用すると、未定義の結果が生成されます。
についてprintf
/ sprintf
:
7. c変換指定子の場合:引数に数値がある場合は、その値でエンコードされた文字を出力する必要があります。値が0の場合または、文字セットの文字エンコーディングではありません。動作が定義されていません。。
したがって、これはNUL文字を取得する別の方法であるため、未定義の動作が発生します。
要約すると、awk
POSIXはNUL文字を入力、出力、変数の保存など、移植可能に使用できないことを伝えます。
gawk
(少なくとも1989年2.10以降、これは私が見つけることができる最も初期のバージョンです。NULサポート文書化)と@トーマスディキmawk
(からバージョン 20140914)はNULを処理できる2つの実装です。
答え2
awk
C文字列には通常、デフォルトではCタイプのインタプリタであるnullバイトを含めることはできません。 NULLバイトを印刷できるPOSIXユーティリティは、POSIX標準で明示的に参照する必要があります。printf
しかしawk
それは真実ではない。
以下の状況は POSIX に明示的にリストされています。
echo 'x\0000y'
printf 'x\000y\n'
printf '%b\n' 'x\0000y'
3つのコマンドはすべて、POSIX UNIXブランドの認証済みオペレーティングシステムから4文字を印刷します。
あなたのawk
例では、指定されていない動作を使用します。