Eu esperaria que o bash sort comparasse strings como esta:
- Comece no primeiro caractere (de ambas as strings)
- Se os caracteres forem iguais, prossiga para o próximo caractere
- Se eles forem desiguais, retorne o resultado maior/menor para o algoritmo de classificação
- Se não houver mais caracteres, retorne igual
Por alguma razão, parece que este não é o caso.
Vamos pegar a seguinte entrada:
a
b
.
-
Isso é classificado por bash sort como
-
.
a
b
Agora, para entrada
b.de
bb.de
Eu esperaria o seguinte resultado de classificação:
b.de
bb.de
Porque o primeiro caractere é igual, e para o segundo caractere, .
vem antes b
(como visto no primeiro teste).
Por alguma razão, este não é o caso, as strings são classificadas assim:
bb.de
b.de
Por que está sort
se comportando dessa maneira e existe uma maneira de fazer com que ele se comporte "conforme o esperado"?
Eu testei os mesmos exemplos com python e python classifica conforme esperado.
Classificar por padrão faz uma classificação com reconhecimento de localidade que usa as regras lexicográficas de sua localidade. veja strcoll(3)
ltrace(3) me deu isto:
strcoll("b.de", "bb.de") = 20
comparações com reconhecimento de localização parecem dividir as strings em palavras e classificá-las. já que as palavras nunca começam com '.' sort vê palavras com 0 lenfgh e as coloca no início da lista. no entanto '.' é colocado em palavras, por exemplo: "Jr." "Ph.D"
se você precisar de uma comparação de bytes, exporte LC_COLLATE=C ou LC_COLLATE=POSIX
Eu verifiquei o
coreutils
pacote e se você não fornecer nenhum argumento, parece que ele (eventualmente) usa astrcmp
rotina C. O único caso que não é verdade é quando os valores nas linhas podem ser interpretados como números inteiros.A página de manual da qual diz:
Isso significa que o
strcmp
ofbb.de
eb.de
realmente se resume ao último caractere.Isso é
if 'd' < 'e'
o que (pelo menos em ascii) seriaif 100 < 101
o que é verdade.