ɛ
("Latin epsilon") é uma letra usada em certas línguas africanas, geralmente para representar o som da vogal em inglês "bed". Em Unicode é codificado como U+025B, muito diferente do e
.
No entanto, se eu sort
o seguinte:
eb
ed
ɛa
ɛc
parece que sort
considera ɛ
e e
equivalente:
ɛa
eb
ɛc
ed
O que está acontecendo aqui? E existe uma maneira de fazer ɛ
e e
distinguir para sort
fins de ing?
Não, não os considera equivalentes, apenas têm o mesmo peso primário. Então, em primeira aproximação, eles classificam o mesmo.
Se você olhar para /usr/share/i18n/locales/iso14651_t1_common (como usado como base para a maioria das localidades) em um sistema GNU (aqui com glibc 2.27), você verá:
e
,ɛ
eE
têm o mesmo peso primário,e
eE
mesmo peso secundário, apenas o terceiro peso os diferencia.Ao comparar strings,
sort
(astrcoll()
função libc padrão é usada para comparar strings) começa comparando os pesos primários de todos os caracteres, e só vai para o segundo peso se as strings forem iguais aos pesos primários (e assim por diante com os outros pesos) .É assim que o caso parece ser ignorado na ordem de classificação em primeira aproximação.
Ab
classifica entreaa
eac
, masAb
pode classificar antes ou depoisab
dependendo da regra do idioma (alguns idiomas têm<MIN>
antes<CAP>
como em inglês britânico, alguns<CAP>
antes<MIN>
como em estoniano).Se
e
tivesse a mesma ordem de classificação queɛ
,printf '%s\n' e ɛ | sort -u
retornaria apenas uma linha. Mas como<BAS>
classifica antes<PCL>
,e
só classifica antesɛ
.eɛe
classifica depoisEEE
(no peso secundário) mesmo queEEE
classifica depoiseee
(para o qual precisamos ir até o terceiro peso).Agora, se no meu sistema com glibc 2.27, eu corro:
Você notará que existem alguns caracteres que foram definidos com exatamente os mesmos 4 pesos. Em particular, nosso ɛ tem os mesmos pesos que:
E com certeza:
Isso pode ser visto como um bug de localidades GNU libc. Na maioria dos outros sistemas, as localidades garantem que todos os caracteres diferentes tenham uma ordem de classificação diferente no final. Em localidades GNU, fica ainda pior, pois existem milhares de caracteres que não têm uma ordem de classificação e acabam classificando da mesma forma, causando todos os tipos de problemas (como quebrar
comm
,join
,ls
ou globs com ordens não determinísticas ... ), daí a recomendação de usarLC_ALL=C
para contornar esses problemas .Conforme observado por @ninjalj nos comentários, o glibc 2.28 lançado em agosto de 2018 veio com algumas melhorias nessa frente, embora o AFAICS, ainda existam alguns caracteres ou elementos de agrupamento definidos com ordem de classificação idêntica. No Ubuntu 18.10 com glibc 2.28 e em uma localidade en_GB.UTF-8.
(por que U+00B7 seria considerado equivalente a U+0387 somente quando combinado com
L
/l
?!).E:
(ainda mais de 1 milhão de caracteres (95% do intervalo Unicode, abaixo de 98% em 2.27) classificando da mesma forma que outros caracteres, pois sua ordem de classificação não está definida).
Veja também:
homem tipo:
Então tente:
LC_ALL=C sort file.txt
O caractere ɛ não é igual a e, mas alguns locais podem reunir esses sinais juntos após a ordenação. A razão para isso é específica da linguagem, mas também de algum contexto histórico ou mesmo político. Por exemplo, a maioria das pessoas provavelmente espera que a moeda €uro chegue perto da Europa no dicionário.
De qualquer forma, para ver qual agrupamento você está usando no momento, run
locale
, olocale -a
fornecerá a lista de localidades disponíveis no sistema e, para alterar o agrupamento, digamosC
apenas para uma execução de classificaçãoLC_COLLATE=C sort file
. Finalmente, para ver como diferentes localidades podem classificar seu arquivo, tenteEncaminhe o resultado para alguma ferramenta greping para escolher a localidade que atenda às suas necessidades.