¿Por qué el registro no numérico se muestra después de "0" en la clasificación?

8

Quiero ordenar los archivos según el número en el nombre del archivo. Aquí están los archivos:

$ ls *.f
0.f  13.f  1.f  22.f  4.f  abc.f

El resultado de la clasificación:

$ ls *.f | sort -t. -k1n
0.f
abc.f # note this file!
1.f
4.f
13.f
22.f

Lo que esperaba era:

$ ls *.f | sort -t. -k1n
abc.f
0.f
1.f
4.f
13.f
22.f

¿Por qué se abc.fmostró justo después 0.fy antes 1.f? ¿Es porque 0no es tratado como un número por sort? Busqué en la web y no encontré ninguna referencia.

nn0p
fuente
Sigue siendo el mismo después de agregar LC_ALL=C.
nn0p

Respuestas:

12

La razón es porque cuando se usa la ordenación numérica, las cadenas sin números se tratan como cero. GNU sort consigue el comportamiento correcto, pero no hace ningún comentario sobre por qué. La página de manual de illumos para SunOS ofrece una explicación:

-n
Restringe la clave de clasificación a una cadena numérica inicial, que consta de caracteres en blanco opcionales, signo menos opcional y cero o más dígitos con un carácter de raíz opcional y separadores de miles (como se define en la configuración regional actual), que se ordena por valor aritmético . Una cadena de dígitos vacía se trata como cero. Los ceros a la izquierda y los signos en ceros no afectan el orden.

Este comportamiento también se especifica en SUSv4 y POSIX.1-2008 ( http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sort.html ), utilizando el mismo lenguaje que la página de manual de illumos.

La ordenación GNU también tiene -g"ordenación numérica general", que ordena por números de coma flotante en lugar de enteros donde las cadenas de dígitos vacías se ordenan antes de cero. No estoy seguro de si esto es un efecto secundario o intencional. Sin embargo, -gviene con una advertencia ya que es significativamente más lenta que -n. Si está ordenando un gran conjunto de datos o haciendo algo que los usuarios esperan, debe evitarlo -g.

bahamat
fuente
Para completar, también debe mencionar cómo se sortmaneja con dos líneas que tienen la misma clave.
kasperd
1

puedes usar -g

-g, --general-numeric-sort compare según el valor numérico general

root@virt01-ubuntu:~# ls  | sort -t. -k1g
a.txt
0.txt
1.txt
2.txt
3.txt
root@virt01-ubuntu:~#
rɑːdʒɑ
fuente