ASCII文字の範囲は0から127です。この範囲内で、%c書式指定子を使用するawkのprintfは、1バイトのデータを出力します。
$ awk 'BEGIN{printf "%c", 97}'
a
$ awk 'BEGIN{printf "%c", 127}' | xxd
00000000: 7f
$ awk 'BEGIN{printf "%c", 127}' | xxd -b
00000000: 01111111
ただし、127より大きい値の場合は、複数バイトを印刷します。
$ awk 'BEGIN{printf "%c", 128}' | xxd
00000000: c280
$ awk 'BEGIN{printf "%c", 128}' | xxd -b
00000000: 11000010 10000000
0xc280の意味は何ですか? awkが0x80の代わりにこの文字を出力するのはなぜですか?
答え1
これはUTF-8コーディング。 11000010は2バイトシーケンスを開始し(最初の2ビットはクリアビットに設定されます)、有効なビットは00010000000(最初のバイトの最後の5ビット、2番目のバイトの最後の6ビット)です。これは128です。 。
AWKはロケールがUTF-8を使用するように設定されているため、それを出力します。 UTF-8以外のロケールに切り替えることで、違いを確認できます。
$ LC_ALL=C awk 'BEGIN{printf "%c", 128}' | xxd -b
00000000: 10000000
答え2
ロケールがUTF8、POSIX、またはCであるかどうかにかかわらず、任意のバイトを印刷するようにawkを取得する1つのトリックは、符号なしバイト条例値に256の大きな倍数を追加し、新しい数値がUnicode 0x10FFFF
14制限仕様を超えるようにするです。
以下は、UTF8でエンコードされた文字を印刷するためにgawkバイトモードでランダムバイトにアクセスする方法のデモです。 gawk Unicodeモードでも、同じ方法で任意のバイトにアクセスできます。
gawk -e 'BEGIN { printf("%c",50000) }' | od -baxco -t dC
0000000 354 215 220
? 8d 90
8dec 0090
썐 ** **
106754 000220
-20-115-112
0000003
% gawk -b -e 'BEGIN { printf("%c%c%c",
(-20)+8^8,
(-115)+8^8,
(-112)+8^8) }' | od -baxco -t dC
0000000 354 215 220
? 8d 90
8dec 0090
썐 ** **
106754 000220
-20-115-112
0000003
% gawk -e 'BEGIN { printf("%c%c%c%c",\
\
0xAB+8^8, 0xBA+8^8, \
0xCA+8^8, 0xFE+8^8) }' \
| god --endian=big -baxco -t dCxI
0000000 253 272 312 376
+ : J ~
abba cafe
? ? ? ?
125672 145376
-85 -70 -54 -2
abbacafe
0000004
この方法は、ロケールに関係なく機能します。
mawk-1、mawk2-beta、およびnawkの場合、符号なしバイト値から256を減算して負の数printf("%c")
を使用することもできます。 gawkはこれを許可しましたが、最新バージョンではこれを無効にした可能性があります。