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비트, 두 번째 바이트의 마지막 6비트)이며 이는 128입니다. .
AWK는 로케일이 UTF-8을 사용하도록 설정되어 있으므로 이를 출력합니다. UTF-8이 아닌 로케일로 전환하여 차이점을 확인할 수 있습니다.
$ LC_ALL=C awk 'BEGIN{printf "%c", 128}' | xxd -b
00000000: 10000000
답변2
로케일이 UTF8, POSIX 또는 C인지 여부에 관계없이 임의의 바이트를 인쇄하도록 awk를 얻는 한 가지 트릭은 부호 없는 바이트 조례 값에 256의 큰 배수를 추가하여 새 숫자가 유니 0x10FFFF
코드 14 제한 사양을 초과하도록 하는 것입니다.
다음은 UTF8로 인코딩된 문자를 인쇄하기 위해 gawk 바이트 모드에서 임의의 바이트에 액세스하는 방법에 대한 데모입니다. gawk 유니코드 모드에서도 동일한 방법을 사용하여 임의의 바이트에 액세스할 수 있습니다.
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는 이를 허용했지만 최신 버전에서는 이를 비활성화했을 수 있습니다.