unix ls – ¿Por qué la clasificación de ls ignora los caracteres no alfanuméricos?

Pregunta:

Al ordenar los nombres de los archivos, ls ignora caracteres como -,_ . Esperaba que también usara esos caracteres en la clasificación.

Un ejemplo:

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

Ahora muestre estos archivos con ls -1 :

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

Lo que esperaba era algo como esto:

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

es decir, esperaba que los caracteres no alfanuméricos se tuvieran en cuenta al ordenar.

¿Alguien puede explicar este comportamiento? ¿Este comportamiento es obligatorio por un estándar? ¿O se debe a que la codificación es UTF-8?

Actualización: parece que esto está relacionado con la clasificación 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

Respuesta:

EDITAR: Prueba agregada para datos ordenados con LC_COLLATE = C


La secuencia de clasificación predeterminada trata esos caracteres de "tipo de puntuación" como si Use LC_COLLATE=C mismo valor. Use LC_COLLATE=C para tratarlos en el orden de los puntos de código.

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

Producción

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

El siguiente código prueba todos los caracteres UTF-8 válidos en el plano multilingüe básico (excepto \ x00 y \ x0a ; para simplificar)
Compara un archivo en una secuencia ascendente conocida (generada) con ese archivo ordenado aleatoriamente y luego ordenado nuevamente con LC_COLLATE = C. El resultado muestra que la secuencia C es idéntica a la secuencia generada original.

{ 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 $?='$?

Producción:

63485c63485
< last line of listOrig 
---
> last line of listCsort

cmp $?=0

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top

web tasarım