일부 유니 코드 문자가 터미널에 인쇄되지 않는 이유는 무엇입니까?


16

Adobe Source Code Pro 글꼴을 사용하여 간단한 터미널로 Arch Linux를 실행하고 있습니다. 내 로케일이로 설정되었습니다 LANG=en_US.UTF-8.

카드 놀이를 나타내는 유니 코드 문자를 터미널에 인쇄하고 싶습니다. 참조 용으로 Wikipedia를 사용하고 있습니다.

카드 한 벌의 유니 코드 문자가 제대로 작동합니다. 예를 들어, 발행

$ printf "\u2660"

화면에 검은 마음을 인쇄합니다.

그러나 특정 카드 놀이에 문제가 있습니다. 발행

$ printf "\u1F0A1"

Ἂ1스페이드 에이스 대신 기호 를 인쇄합니다 . 무슨 일이야?

이 문제는 여러 터미널 (urxvt, xterm, termite)과 내가 시도한 모든 글꼴 (DejaVu, Inconsolata)에 걸쳐 지속됩니다.


경고 : 이것이 printf에 의해 처리되면 비표준 향상입니다. 따라서 그러한 탈출이 전혀 효과를 기대하지 마십시오. 참조 : pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html
schily

답변:


27

help printfprintf(1)해석 된 이스케이프 시퀀스는 지연되고 GNU printf 문서 는 다음 과 같이 말합니다.

printf해석 ISO C (99)에 도입 된 두 문자 구문을 : \u16 진수 4 개 디지트로 지정된 16 비트 유니 코드 (ISO / IEC 10646) 문자에 대한 HHHH\U여덟 진수 자리로 지정된 32 비트 유니 코드 문자를위한 HHHHHHHH . 로케일 printf에 따라 유니 코드 문자를 출력합니다 LC_CTYPE. U + 0024 ($), U + 0040 (@) 및 U + 0060 (`)을 제외하고 U + 0000… U + 009F, U + D800… U + DFFF 범위의 유니 코드 문자는이 구문으로 지정할 수 없습니다. .

비슷한 뭔가가에 대한 배쉬 설명서에 지정된 ANSI C는 인용echo:

\uHHHH
값이 16 진수 값 HHHH (1-4 자리 16 진수) 인 유니 코드 (ISO / IEC 10646) 문자

\UHHHHHHHH
값이 16 진수 값 HHHHHHHH ( 1-8 자리 16 진수) 인 유니 코드 (ISO / IEC 10646) 문자

한마디로 : \u5 자리 16 진수가 아닙니다. 그것은 \U:

# printf "\u2660 \u1F0A1 \U1F0A1\n"
 1 🂡

2

Muru의 답변은 완전히 정확하지만 한 가지 요점을 명확히하기 위해 :

인쇄 할 때 \u1F0A116 비트 유니 코드 이스케이프로 해석되고 \u1F0A그 뒤에 리터럴 문자 가 해석됩니다 1( \u따라서 다음 문자를 사용 하므로 더 이상은 안됩니다). 그런 다음 U + 1F0A 는 몇 분음 부호가있는 그리스 알파 ( Psili 및 Varia가 포함 된 그리스 대문자 알파 )를 제공합니다.

유니 코드 이스케이프에서 16 비트 이상을 원하면 \U8 자의 16 진수가 필요한을 사용해야 \U0001F0A1합니다. 재생 카드를 제공합니다.


\U0001F0A1실제로보다 이식성이 뛰어납니다 \U1F0A1. GNU 독립 실행 형 printf유틸리티는 처음에 해당 \uXXXX/ \UXXXXXXXX시퀀스를 도입 했으며 4 자리 숫자 \u와 8 자리 숫자가 필요 합니다 \U. printfGNU 쉘 내장, ksh93 및 zsh와 같은 다른 구현은 더 느슨합니다. 어쨌든 printf '\u/\U'POSIX가 아닙니다. 그러나 POSIX는 zsh를 지정 $'\U1F0A1'하며 8 자리를 모두 요구하지는 않습니다.
Stéphane Chazelas

@ StéphaneChazelas 흥미롭게도, 나는 POSIX가 8 자리 숫자와 함께 갈 것이라고 항상 생각했습니다. 코드 뒤에 추가 문자와 숫자를 캡처하지 않으려면 8 자리 버전이 zsh에서 여전히 유효하다고 가정합니까?
Draconis

예, \uxxxx있습니다 최대 4 개 자리하고 \Uxxxxxxxx있다 최대 8 자리. 유니 코드는 이제 코드 포인트 0에서 0x10FFFF (UTF16에서 가져온 제한)로 제한되므로 코드 포인트는 절대 6 자리를 넘지 않습니다 (여전히 \U123456789코드 포인트 0x12345678의 문자로 해석 9되고 실패 함). POSIX 사양 $'\u\U'은 아직 확정되지 않았습니다 ( austingroupbugs.net/view.php?id=249 참조 ). 이전 초안에서는 4/8 자리가 모두 필요했지만 나중에 변경되었습니다 (요청시).
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.