Il comando cut
ha un'opzione -c
per lavorare sui caratteri, anziché sui byte con l'opzione -b
. Ma questo non sembra funzionare, in en_US.UTF-8
locale:
Il secondo byte fornisce il secondo carattere ASCII (che è codificato esattamente nello stesso UTF-8):
$ printf 'ABC' | cut -b 2
B
ma non fornisce il secondo dei tre caratteri greci non ASCII nelle impostazioni internazionali UTF-8:
$ printf 'αβγ' | cut -b 2
�
Va bene, è il secondo byte .
Quindi guardiamo invece al secondo personaggio :
$ printf 'αβγ' | cut -c 2
�
Sembra rotto.
Con alcuni esperimenti, si scopre che l'intervallo 3-4
mostra il secondo carattere:
$ printf 'αβγ' | cut -c 3-4
β
Ma è lo stesso dei byte da 3 a 4:
$ printf 'αβγ' | cut -b 3-4
β
Quindi il -c
non è più che -b
per UTF-8.
Mi aspetto che l'impostazione della locale non sia corretta per UTF-8, ma in confronto wc
funziona come previsto;
Viene spesso usato per contare i byte, con option -c
( --bytes
).
(Nota i nomi delle opzioni confuse.)
$ printf 'αβγ' | wc -c
6
Ma può anche contare i caratteri con option -m
( --chars
), che funziona semplicemente:
$ printf 'αβγ' | wc -m
3
Quindi la mia configurazione sembra essere ok, ma qualcosa di speciale cut
.
Forse non supporta affatto UTF-8? Ma sembra supportare caratteri multi-byte, altrimenti non avrebbe bisogno di supportare -b
e -c
.
Allora, cosa c'è che non va? E perché?
Il setup della localizzazione sembra giusto per utf8, per quanto ne so:
$ locale
LANG=en_US.UTF-8
LANGUAGE=en_US
LC_CTYPE=en_US.UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
L'ingresso, byte per byte:
$ printf 'αβγ' | hd
00000000 ce b1 ce b2 ce b3 |......|
00000006
-c
stia usando lo stesso codice di-b
. Hai dato un'occhiata al codice sorgente? Forse puoi trovare un suggerimento per cosa-c
è realmente pensato.