Awk
為什麼 awk 的 printf 將大於 127 的字元值解釋為多字節字元?
ASCII 字元範圍是從 0 到 127,在該範圍內,帶有 %c 格式說明符的 awk 的 printf 輸出一個字節的數據:
$ 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?
這是UTF-8編碼。11000010 開始一個兩字節序列(前兩位置位後跟一個清零位),有效位為 00010000000(第一個字節的後五位,第二個字節的後六位),即 128 .
AWK 正在輸出此內容,因為您的語言環境設置為使用 UTF-8;您可以切換到非 UTF-8 語言環境以查看差異:
$ LC_ALL=C awk 'BEGIN{printf "%c", 128}' | xxd -b 00000000: 10000000
讓 awk 列印出任意字節的一個技巧,無論您的語言環境是 UTF8 還是 POSIX 還是 C,都是將 256 的大倍數添加到無符號字節條例值中,以帶來上面的新數字
0x10FFFF
,即 Unicode 14 的限制規格。這是一個展示如何在 gawk 字節模式下訪問任意字節以列印出 UTF8 編碼的字元。同樣的方法也可以用於 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 過去也允許這樣做,但最近的版本可能已禁用它。