Por que o 'ls' lista os seguintes arquivos em ordens aparentemente diferentes?

3

Por que o ls lista os seguintes arquivos em ordens aparentemente diferentes?

Por padrão, não ls lista arquivos na ordem lexicográfica da minha localidade atual, que eu acho que é a padrão?

$ ls
a_1  a_10  a_11  a_12

$ ls
a_10-18  a_11-18  a_1-18  a_12-18

Eu tenho alias ls='ls --color=auto' e LC_COLLATE="en_US.UTF-8" .

    
por Tim 05.12.2016 / 17:29

2 respostas

5

O local é realmente complicado. O objetivo é obter algo que "pareça normal" para usuários não técnicos. (O pessoal técnico pode usar LANG=C para obter essa sensação de calor.) A definição técnica é um documento padrão Unicode , e eu tentei destilar um pouco disso aqui. Correções recebidas com alegria.

Acho interessante ler que locale é uma propriedade do usuário que manipula os dados, não dos dados em si. O documento técnico faz alguns esforços para esclarecer isso com referência à ordem de classificação para um usuário alemão que é diferente da de um usuário sueco, mesmo que os caracteres usados nas sequências de exemplo sejam os mesmos.

As localidades en_GB e en_US estão configuradas para ignorar o caractere - . Muito simplificadas, as regras de classificação desses locais para a ordem crescente são:

  1. O caso é insensível
  2. Se você tiver duas strings em que uma é a mesma e a outra, mas mais longa, ela classifica em segundo. Então xyzA é sempre depois de xyz
  3. Alguma pontuação (nessa situação incluindo - ) é ignorada, a menos que seja comparada a outra pontuação
  4. Digitar classificar antes das letras
  5. Os dígitos são classificados 0 .. 9
  6. As letras são classificadas [Aa] .. [Zz] (en_GB e en_US não têm sotaque)
  7. A pontuação é classificada (mas não é relevante para os exemplos nesta resposta)

Aplicando essas regras aos conjuntos de dados em questão:

a_1  a_10  a_11  a_12

Isso equivale a a1 a10 a11 a12 e, considerando a regra 2, obtemos que a1 deve ser antes de a10 e a11 . Qualquer coisa diferente de a1 tem o mesmo número de caracteres alfanuméricos para que possam ser comparados de forma consistente. Isso nos dá a_1 a_10 a_11 a_12 .

a_10-18  a_11-18  a_1-18  a_12-18

Aplicam-se as mesmas regras, exceto que o número 3 também se aplica (ignoramos pontuação). Isso significa que podemos considerar os valores como a_1018 a_1118 a_118 a_1218 e, seguindo as regras # 2 e # 4, recebemos o pedido a_10-18 a_11-18 a_1-18 a_12-18 .

Tomando nosso exemplo final dos comentários

a_10 a_10- a_100 a_101 a_10-18 a_102

Regras # 3 e, em seguida, # 2, # 4 se aplicam. Portanto, removemos (ignoramos) os caracteres - , o que nos dá a_10 a_10 a_100 a_101 a_1018 a_102 e classificamos o restante pelo prefixo de subcadeia comum e depois pela ordem dos caracteres.

(Não está claro para mim se temos a_10 e, em seguida, a_10- em virtude da extensão, ou apenas porque acaba sendo assim. Estou tentado a sugerir a segunda opção, mas eu amar alguém para confirmar isso.)

    
por 06.12.2016 / 01:27
1

Na ordem lexicográfica, a_1 vem antes de qualquer outra cadeia começando com a_1 . Como os dígitos estão em ordem numérica em qualquer local razoável, segue-se que em qualquer localidade razoável, a_1 < a_10 < a_11 < a_12 .

Se você adicionar um sufixo comum a essas cadeias, a ordem poderá ser alterada porque esse sufixo comum pode ser classificado em algum lugar no meio. No segundo exemplo, há quatro strings começando com o prefixo comum a_1 e com os respectivos sufixos 0-18 , 1-18 , -18 e 2-18 . Na localidade C, as cadeias são comparadas em uma base lexicográfica estrita; - vem antes dos dígitos, então -18 vem primeiro: a_10-18 < a_11-18 < a_1-18 < %código%. Mas a maioria dos outros locais são mais complicados. Em particular, a pontuação é ignorada, exceto como último recurso. Então, para comparar as cordas a_12-18 < a_10-18 < a_11-18 < a_1-18 , compare primeiro as sequências sem pontuação a_12-18 , a1018 a1118 a118 ; a ordem do segundo dígito é a1218 < 0 < 1 < 1 e, para as duas cadeias intermediárias, a ordem do terceiro dígito é 2 < %código%. Se você adicionar uma string que difira apenas na pontuação, a pontuação diferente determinará como ela é classificada, por exemplo, 1 < 8 < a_10-18 < a_1-118

A explicação na minha resposta é simplificada. Pode haver mais de dois passes, para lidar com coisas como pontuação. O Guia do Usuário do ICU tem uma explicação bastante detalhada (mas mesmo isso não lida com todas as sutilezas que entram na classificação coisas como índices de livros).

    
por 06.12.2016 / 01:28

Tags