Używam Arch Linux z prostym terminalem, używając czcionki Adobe Source Code Pro. Moje ustawienia regionalne są poprawnie ustawione na LANG=en_US.UTF-8
.
Chcę wydrukować na moim terminalu znaki Unicode reprezentujące karty do gry. Korzystam z Wikipedii w celach informacyjnych .
Znaki Unicode dla kolorów kart działają dobrze. Na przykład wydawanie
$ printf "\u2660"
drukuje czarne serce na ekranie.
Mam jednak problemy z określonymi kartami do gry. Wydawanie
$ printf "\u1F0A1"
wypisuje symbol Ἂ1
zamiast asa pik 🂡. Co jest nie tak?
Ten problem występuje na kilku terminalach (urxvt, xterm, termite) i na każdej wypróbowanej czcionce (DejaVu, Inconsolata).
Odpowiedzi:
help printf
odkłada naprintf(1)
interpretowane sekwencje specjalne, a dokumentacja GNU printf mówi:Coś podobnego podano w podręczniku Bash dla ANSI C Quoting i
echo
:W skrócie:
\u
nie jest dla 5 cyfr szesnastkowych. To jest\U
:źródło
Odpowiedź Muru jest całkowicie poprawna, ale tylko w celu wyjaśnienia jednego punktu:
Podczas drukowania
\u1F0A1
jest to interpretowane jako szesnastobitowe wyjście Unicode\u1F0A
, po którym następuje dosłowny znak1
(ponieważ\u
zajmuje cztery następujące znaki, nie więcej, nie mniej). U + 1F0A daje następnieἊ
grecką alfę z kilkoma znakami diakrytycznymi ( dokładniej grecka litera Alpha z Psili i Varią ).Jeśli chcesz więcej niż szesnaście bitów w ucieczce Unicode, musisz użyć
\U
, który wymaga heksa o wartości ośmiu znaków:\U0001F0A1
da ci kartę do gry.źródło
\U0001F0A1
jest w rzeczywistości bardziej przenośny niż\U1F0A1
. Jest to samodzielneprintf
narzędzie GNU , które jako pierwsze wprowadziło te\uXXXX
/\UXXXXXXXX
sekwencje i wymaga 4 cyfr dla\u
i 8 dla\U
. Inneprintf
implementacje, takie jak wbudowana powłoka GNU, ksh93 i zsh, są bardziej luźne. W każdym razieprintf '\u/\U'
nie jest POSIX. POSIX określi jednak parametry zsh$'\U1F0A1'
i nie będzie wymagał wszystkich 8 cyfr.\uxxxx
jest aż do 4 cyfr i\Uxxxxxxxx
jest aż do 8 cyfr. Zauważ, że Unicode jest teraz ograniczony do współrzędnych kodowych od 0 do 0x10FFFF (ograniczenie wprowadzone przez UTF16), więc punkty kodowe nigdy nie będą miały więcej niż 6 cyfr (nadal\U123456789
będą interpretowane jako znak punktu kodowego 0x12345678, po którym9
nastąpi błąd). Specyfikacja POSIX dla$'\u\U'
wciąż nie jest sfinalizowana (patrz austingroupbugs.net/view.php?id=249 ). We wcześniejszej wersji wymagały wszystkich 4/8 cyfr, ale zmieniły się później (na moją prośbę).