O comando cut
tem uma opção -c
para trabalhar em personagens, em vez de bytes com a opção -b
. Mas isso não parece funcionar, no en_US.UTF-8
local:
O segundo byte fornece o segundo caractere ASCII (que é codificado da mesma forma em UTF-8):
$ printf 'ABC' | cut -b 2
B
mas não fornece o segundo dos três caracteres gregos não ASCII no código do idioma UTF-8:
$ printf 'αβγ' | cut -b 2
�
Está tudo bem - é o segundo byte .
Então, olhamos para o segundo caractere :
$ printf 'αβγ' | cut -c 2
�
Isso parece quebrado.
Com algumas experiências, verifica-se que o intervalo 3-4
mostra o segundo caractere:
$ printf 'αβγ' | cut -c 3-4
β
Mas isso é igual aos bytes 3 a 4:
$ printf 'αβγ' | cut -b 3-4
β
Portanto, o valor -c
não é superior ao -b
UTF-8.
Eu esperaria que a configuração de localidade não seja adequada para UTF-8, mas, em comparação, wc
funciona como esperado;
É frequentemente usado para contar bytes, com a opção -c
( --bytes
).
(Observe os nomes das opções confusas.)
$ printf 'αβγ' | wc -c
6
Mas também pode contar caracteres com a opção -m
( --chars
), que simplesmente funciona:
$ printf 'αβγ' | wc -m
3
Portanto, minha configuração parece estar correta - mas algo é especial cut
.
Talvez ele não suporte UTF-8? Mas parece suportar caracteres de vários bytes, caso contrário não precisaria suportar -b
e -c
.
Então, oque há de errado? E porque?
A configuração da localidade parece correta para utf8, até onde eu sei:
$ 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=
A entrada, byte a byte:
$ printf 'αβγ' | hd
00000000 ce b1 ce b2 ce b3 |......|
00000006
-c
está usando o mesmo código que-b
. Você deu uma olhada no código fonte? Talvez você possa encontrar uma dica para o que-c
realmente se destina.