Lista de archivos ordenados numéricamente


123

Tengo un montón de archivos de log1a log164.

Estoy tratando de LISTAR el directorio (ordenado) en un terminal UNIX, pero las funciones de clasificación solo proporcionan el formato de esta manera:

home:logs Home$ ls -1 | sort
log1.gz
log10.gz
log100.gz
log101.gz
log102.gz
log103.gz
log104.gz
log105.gz
log106.gz
...etc

Lo que quiero es

home:logs Home$ ls -1 | sort
log1.gz
log2.gz
log3.gz
log4.gz
log5.gz
log6.gz
log7.gz
...{more here}
log99.gz
log100.gz
log101.gz
log102.gz
...etc

¿Alguna sugerencia sobre lo que podría usar para hacer esto?


8
¡Esta es absolutamente una pregunta de programación, y no merece ser migrada solo porque la respuesta involucra el lenguaje de programación de bajo nivel!
tchrist

Si usted sabe de antemano que están nombrados log1.gza través log164.gz, entonces, ¿qué es lo que aún necesita ls -1de ellos para?
ruakh

1
@ruakh ls -1 muestra los resultados en una columna en lugar de a través

3
@Rabiani: Sé lo que ls -1hace: enumera los nombres de archivo. Como ya conocías los nombres de archivo, no entendí para qué lo necesitabas. Pero como has aceptado la respuesta de Kevin, ahora sé: no la necesitabas. Lo que tiene más sentido. :-)
ruakh

Respuestas:


40

bashLos frenos, {}los enumerarán en orden:

for file in log{1..164}.gz; do
    process "$file"
done

267

¿Por qué no utilizar la lsfunción incorporada para este caso en particular?

-v natural sort of (version) numbers within text

Por ejemplo ls -1v log*


Solución impresionante, aunque desearía que hubiera una solución igualmente simple usando sort, en caso de que uno tenga una serie de cadenas en lugar de un directorio de archivos
Hubro

23
En BSD / OS X esta opción es algo más: -v - Force unedited printing of non-graphic characters.
kenorb

Lamentablemente, la opción -v no está disponible en AIX (6.1)
bouvierr

66
Esta debería ser la mejor respuesta.
32r34wgf3e

1
para MacOS esto funcionará, no podría encontrar una opción como se mencionó, solols | sort -n
Ricky Levi

47

Con GNU ls (es decir, en Linux, Cygwin u otros sistemas que tienen GNU ls específicamente instalado):

ls -v

En zsh:

echo *(n)

En otras conchas:

echo log?.gz log??.gz log???.gz

Reemplace echopor printf '%s\n'si desea que cada nombre de archivo esté en una línea separada.

Si también desea metadatos de archivo ( ls -l) y no tiene GNU ls, deberá llamar lspor separado para cada nombre de archivo o grupo de nombres de archivo que desea ver en orden lexicográfico.

ls -ld log?.gz; ls -ld log??.gz; ls -ld log???.gz

Para evitar estas dificultades, use suficientes ceros a la izquierda en los nombres de sus archivos para que el tipo lexicográfico sea amigable para los humanos ( log001.gz, etc.).


29

Si bien la solución ls -1ves ciertamente la mejor en este caso particular, creo que es bueno tener también una que funcione sortcomo en la pregunta original, ya que esto también funciona cuando su entrada no proviene ls. En este caso puedes usar:

ls -1 | sort -n -k1.4

La -nopción le dice a sort que clasifique numéricamente y -k 1.4establece la clave de clasificación en el primer campo (que es el nombre de archivo completo en este caso) comenzando desde el 4º carácter hasta el último.


En mi caso, ls -1 | sort -n -k1.4no funciona. Le da a los no clasificados al principio hasta 4 caracteres y luego los ordenados después del 4 ° carácter. En su ls -1 |sort | sort -n -k1.4lugar, utilicé y funcionó perfectamente.
Prabhu

3
@Prabhu, en cambio, podrías hacerlo sort -k1.1,1.3 -k1.4n. sortNo es necesario que las implementaciones sean estables, por lo que su enfoque no funcionará con todas las implementaciones. Vea también la -Vopción de GNU y FreeBSD sort.
Stéphane Chazelas

21

El GNU sort(como está disponible en Linux) tiene un modo de "clasificación de versiones" que interpreta los números dentro de números que no son números de la manera que usted solicita:

De man 1 sort:

    -V, --version-sort
           natural sort of (version) numbers within text

(Creación de archivos de prueba vacío a la lista:
touch log1.gz log2.gz log3.gz log99.gz log100.gz log101.gz log102.gz)

Su caso de ejemplo, agregando la -Vopción (o --version-sort):

ls -1 log*.gz | sort -V
log1.gz
log2.gz
log3.gz
log99.gz
log100.gz
log101.gz
log102.gz


3

Mi versión de Solaris no es compatible ls -v(grrr). Y la solución de clasificación proporcionada anteriormente 1) requiere el conocimiento de la posición de los dígitos en el nombre del archivo, y 2) no maneja cosas como números de versión de varias partes.

El siguiente enfoque es compatible con Solaris, no requiere conocimiento previo de las posiciones de los dígitos y maneja los números de versión con 2, 3 o 4 componentes (como: a-1.2, foo-5.6.7, bar_baz_9.10.11.12). También se usa sort -fpara plegar mayúsculas y minúsculas, y maneja correctamente directorios entremezclados con archivos:

ls -d | sort -f -t . -k 1,1 -k 2,2n -k 3,3n -k 4,4n

Tenga en cuenta que esta versión limita el primer componente a un solo dígito.

Si su sistema operativo objetivo es compatible ls -v, esa es claramente la solución superior.


1

Solución Perl:

ls log*.gz | perl -ne 'sub getnum{ $_[0] =~ /log(\d+)\.gz/; $1 }; push @A, $_; END{ print sort { getnum $a <=> $b } @A}'

1
$ ls
log101.gz  log102.gz  log103.gz  log104.gz  log105.gz  log106.gz  log10.gz  log1.gz
$ ls | sort -t . -n -k1.4
log1.gz
log10.gz
log101.gz
log102.gz
log103.gz
log104.gz
log105.gz
log106.gz

1
El -t .es superfluo aquí.
Stéphane Chazelas

0

Esto funcionó para mí.

Tengo archivos 1.jpg 2.jpg ... 18.jpg

$ echo *.jpg | tr -s ' ' '\n' | sort -n

sortse está confundiendo con la lssalida debido a los caracteres de color no imprimibles. Si intentas esto:

ls -1 --color=none *.jpg | sort -n

Funcionará perfectamente.

sortpuede ignorar los caracteres no imprimibles con la -iopción, pero todavía no funciona y no sé por qué.

Pero siempre puedes quitar un color como este y sortfuncionará:

ls -1 --color=always *.jpg | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" | sort -n

Espero que algún día sorttenga una opción para esto.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.