En bash, ¿cómo ordenar cadenas con números en ellas?


37

Si tengo estos archivos en un directorio

cwcch10.pdf
cwcch11.pdf
cwcch12.pdf
cwcch13.pdf
cwcch14.pdf
cwcch15.pdf
cwcch16.pdf
cwcch17.pdf
cwcch18.pdf
cwcch1.pdf
cwcch2.pdf
cwcch3.pdf
cwcch4.pdf
cwcch5.pdf
cwcch6.pdf
cwcch7.pdf
cwcch8.pdf
cwcch9.pdf

¿Cómo puedo enumerarlos en Bash para que estén en orden numérico ascendente en función de la parte del número de la cadena. Entonces el orden resultante es cwcch1.pdf, cwcch2.pdf, ..., cwcch9.pdf, cwcch10.pdf, etc.

Lo que finalmente intento hacer es concatenar los archivos PDF pdftkcon algo como lo siguiente

pdftk `ls *.pdf | sort -n` cat output output.pdf

pero eso no funciona ya que mi clasificación es incorrecta.


Gracias por todas las excelentes respuestas a esto. Como siempre con Unix, hay muchas maneras excelentes de desollar este gato.
ngm

Respuestas:


7

Algo como esto podría hacer lo que quieras, aunque tiene un enfoque ligeramente diferente:

pdftk $(for n in {1..18}; do echo cwcch$n.pdf; done) cat output output.pdf

Ajá, buen enfoque! De hecho, hace lo que yo, gracias.
ngm


30

Para este ejemplo en particular, también podría hacer esto:

ls *.pdf | sort -k2 -th -n

Es decir, ordenar numéricamente (-n) en el segundo campo (-k2) usando 'h' como separador de campo (-th).


Dividir y luego ordenar en un campo: es un gran consejo que estoy seguro será útil en el futuro, gracias.
ngm

6

Puede usar la -vopción en GNU ls: tipo natural de números (versión) dentro del texto.

ls -1v cwcch*

Esto no funciona con BSD ls(por ejemplo, en OS X), donde la -vopción tiene un significado diferente.


Esta es la solución más simple, ¡necesita más votos a favor, amigos!
davidparks21

2

Use la expansión de shell directamente en una línea de comandos. La expansión debería ordenarlos correctamente. Si entiendo pdftkla sintaxis de la línea de comandos correctamente, esto hará lo que desee:

# shell expansion with square brackets
pdftk cwcch[1-9].pdf cwcch1[0-9].pdf cat output output.pdf

# shell expansion with curly braces
pdftk cwcch{{1..9},{10..18}}.pdf cat output output.pdf

O puede intentar un enfoque diferente. Cuando necesito hacer algo como esto, generalmente trato de formatear mis números correctamente antes de tiempo. Si llego tarde y los archivos PDF ya están numerados como su ejemplo, lo usaré para volver a numerar:

# rename is rename.pl aka prename -- perl rename script
# this adds a leading zero to single-digit numbers
rename 's/(\d)/0$1/' cwcch[1-9].pdf

Ahora la lsclasificación estándar funcionará correctamente.


2
Quizás un poco más sucintamente:pdftk cwcch{{1..9},{10..18}}.pdf ...
Pausado hasta nuevo aviso.

Un buen consejo, agregado. ¿Es esa una sintaxis de expansión de shell Bourne estándar o una bashextensión?
quack quijote

2

Aquí hay un método que solo usa sort:

ls | sort -k1.6n

0

Ordenar -g se usa para ordenar los números en orden ascendente.

anthony@mtt3:~$ sort --help | egrep "\-g"
-g, --general-numeric-sort  compare according to general numerical value


El siguiente delineador itera sobre un archivo con los nombres de los archivos PDF y toma los números solo con egrep -o y usa sort -g para ordenar los números en orden ascendente . Luego alimenta estos números para sed y los conecta. Luego elimina la salida de duplicados con uniq.


En lugar de uniq, también puedes usar awk:

awk '!x[$0]++'

Lo anterior es equivalente a uniq.


Lo que estás buscando es este revestimiento:

for i in `cat tmp | egrep -o "[0-9]*" | sort -g`; do cat tmp | sed "s/\(^[a-z]*\)\([0-9]*\)\(\.pdf\)/\1$i\3/g" | uniq; done


Contenido de tmp:

anthony@mtt3:~$ cat tmp
cwcch10.pdf
cwcch11.pdf
cwcch12.pdf
cwcch13.pdf
cwcch14.pdf
cwcch15.pdf
cwcch16.pdf
cwcch17.pdf
cwcch18.pdf
cwcch1.pdf
cwcch2.pdf
cwcch3.pdf
cwcch4.pdf
cwcch5.pdf
cwcch6.pdf
cwcch7.pdf
cwcch8.pdf
cwcch9.pdf 

EDITAR:

Salida de comando:

anthony@mtt3:~$ for i in `cat tmp | egrep -o "[0-9]*" | sort -g`; do cat tmp | sed "s/\(^[a-z]*\)\([0-9]*\)\(\.pdf\)/\1$i\3/g" | uniq; done

cwcch1.pdf
cwcch2.pdf
cwcch3.pdf
cwcch4.pdf
cwcch5.pdf
cwcch6.pdf
cwcch7.pdf
cwcch8.pdf
cwcch9.pdf
cwcch10.pdf
cwcch11.pdf
cwcch12.pdf
cwcch13.pdf
cwcch14.pdf
cwcch15.pdf
cwcch16.pdf
cwcch17.pdf
cwcch18.pdf

¿ Este forro funciona en el tmparchivo? ¿Alguna salida para pegar en la respuesta?
Xen2050

Sí. Incluí el resultado en mi OP en la sección de edición.
Aguevara
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.