Pourquoi le sorting de ls ignore-t-il les caractères non alphanumériques?

Lors du sorting des noms de files, ls ignore les caractères tels que -,_ . Je m'attendais à utiliser ces personnages dans le sorting aussi.

Un exemple:

 touch a1 a2 a-1 a-2 a_1 a_2 a.1 a.2 a,1 a,2 

Maintenant, affichez ces files avec ls -1 :

 a1 a_1 a-1 a,1 a.1 a2 a_2 a-2 a,2 a.2 

Ce que j'attendais était quelque chose comme ça:

 a1 a2 a,1 a,2 a.1 a.2 a_1 a_2 a-1 a-2 

c'est-à-dire que je m'attendais à ce que les caractères non alphanumériques soient pris en count lors du sorting.

Quelqu'un peut-il expliquer ce comportement? Ce comportement est-il imposé par une norme? Ou est-ce dû à l'enencoding étant UTF-8?

Mise à jour: Il semble que cela soit lié au sorting UTF-8:

 $ LC_COLLATE=C ls -1 a,1 a,2 a-1 a-2 a.1 a.2 a1 a2 a_1 a_2 

Cela n'a rien à voir avec le charset. C'est plutôt le langage qui détermine l'ordre de classment. La libc examine la langue présentée dans $LC_COLLATE / $LC_ALL / $LANG et search ses règles de classment (par exemple /usr/share/i18n/locales/* pour GLibC) et ordonne le text comme indiqué.

EDIT: Ajout du test pour datatables sortingées avec LC_COLLATE = C


La séquence d'assemblage par défaut traite ces caractères de type ponctuation comme étant de valeur égale. Use LC_COLLATE=C pour les traiter dans l'ordre des codes.

 for i in 'a1' 'a_1' 'a-1' 'a,1' 'a.1' 'a2' 'a_2' 'a-2' 'a,2' 'a.2' ;do echo $i; done |LC_COLLATE=C sort 

Sortie

 a,1 a,2 a-1 a-2 a.1 a.2 a1 a2 a_1 a_2 

Le code suivant teste tous les caractères UTF-8 valides dans le plan multilingue de base (sauf pour \ x00 et \ x0a , pour plus de simplicité)
Il compare un file dans une séquence ascendante connue (générée), par rapport à ce file sortingé randomment puis sortingé à nouveau avec LC_COLLATE = C. Le résultat montre que la séquence C est identique à la séquence générée d'origine.

 { i=0 j=0 k=0 l=0 for i in {0..9} {A..F} ;do for j in {0..9} {A..F} ;do for k in {0..9} {A..F} ;do for l in {0..9} {A..F} ;do (( 16#$i$j$k$l == 16#0000 )) && { printf '.' >&2; continue; } (( 16#$i$j$k$l == 16#000A )) && { printf '.' >&2; continue; } (( 16#$i$j$k$l >= 16#D800 && 16#$i$j$k$l <= 16#DFFF )) && { printf '.' >&2; continue; } (( 16#$i$j$k$l >= 16#FFFE )) && { printf '.' >&2; continue; } echo 0x"$i$j$k$l" |recode UTF-16BE/x4..UTF-8 || { echo "ERROR at codepoint $i$j$k$l " >&2; continue; } echo done done done; echo -n "$i$j$k$l " >&2 done; echo >&2 } >listGen sort -R listGen > listRandom LC_COLLATE=C sort listRandom > listCsort diff <(cat listGen; echo "last line of listOrig " ) \ <(cat listCsort; echo "last line of listCsort" ) echo cmp listGen listCsort; echo 'cmp $?='$? 

Sortie:

 63485c63485 < last line of listOrig --- > last line of listCsort cmp $?=0