Por padrão, sort
classifica caractere por caractere usando uma ordem de classificação especificada pelo local. Geralmente isso é muito próximo da ordem ASCII, mas pode haver algumas variações regionais. Na página do manual:
*** WARNING *** The locale specified by the environment affects sort order.
Set LC_ALL=C to get the traditional sort order that uses native byte values.
Valor de byte nativo geralmente significa valor ASCII, portanto, os dígitos vêm antes das letras maiúsculas, que vêm antes das letras minúsculas. Mas a ordenação ainda é caractere por caractere, então 10
vem antes de 2
porque 1
vem antes de 2
.
Quando a opção -n
ou --numeric-sort
é especificada, as execuções de dígitos são tratadas como números (não caracteres individuais) e classificadas numericamente do menor para o maior.
A documentação não está totalmente explícita nos detalhes, portanto, aqui estão as regras do sinalizador -n
derivado experimentalmente:
- As linhas que começam numericamente são classificadas por valor numérico (números menores vêm primeiro)
- Caracteres finais em linhas numéricas não afetam a parte numérica, mas os caracteres finais são classificados alfanumericamente se a parte numérica for a mesma.
- As linhas que começam não numericamente são classificadas como se fossem zero e, em seguida, pela regra 2.
Observe:
$ printf %s\n 2z 111 10 20b 20a aa2 aa10 | sort -n
aa10
aa2
2z
10
20a
20b
111
Pela Regra 3, as linhas aa10
e aa2
são tratadas como zeros e classificadas pelos caracteres restantes (incluindo os dígitos, que são considerados caracteres).
Pela Regra 2, as linhas 2z
, 20a
e 20b
são tratadas como números e o caractere final só entra em vigor quando os números são iguais.
E pela regra 1, todas as linhas que começam com um número são classificadas por valor numérico.
Sem o sinal -n
, a classificação é feita caractere por caractere, em que os caracteres do dígito vêm antes dos caracteres da carta. Observe:
$ printf %s\n 2z 111 10 20b 20a aa2 aa10 | sort
10
111
20a
20b
2z
aa10
aa2