
Quiero unir algunos archivos png en un pdf. El comando
convert *png out.pdf
Funciona, pero hace el pedido mal. Resulta que
ls -v *png
da el orden que quiero, por lo tanto quiero pasar su resultado para convertirlo.
Yo he tratado
convert `ls -v *png` out.pdf
pero esto no funciona ya que los nombres de los archivos contienen espacios y paréntesis.
Indicar ls
que se establezcan los nombres de archivos entre comillas dobles mediante
convert `ls -vQ *png` out.pdf
tampoco funciona ya que las comillas parecen eliminarse en la sustitución.
¿Qué puedo hacer?
Respuesta1
Si tiene un sistema reciente basado en GNU (que sort
proporciona una -V
clasificación de versión natural similar), puede ordenar usando eso y leer el resultado en una matriz:
while read -rd '' f; do
files+=("$f")
done < <(find . -maxdepth 1 -name '*png' -print0 | sort -zV)
Entonces deberías poder expandir la matriz dentro de tu convert
comando:
convert "${files[@]}" out.pdf
Respuesta2
Si los nombres de sus archivos no tienen líneas nuevas, es posible que pueda hacerlo simplemente diciéndole al shell que divida la salida ls
solo en líneas nuevas, no en espacios en blanco como valor predeterminado. Elterribleestá controlado por la IFS
variable, todos los caracteres contenidos en IFS
se utilizan como delimitadores.
IFS=$'\n' # set it to just a newline
convert $(ls -vd ./*.png) output.pdf
Esto aún puede tener problemas si los nombres de los archivos son lo suficientemente divertidos o si ls
los modifica para mostrarlos. Al imprimir en una terminal, ls
normalmente se enumeran los archivos en varias columnas. Pero cuando la salida no va a una terminal (el shell lo lee aquí), actúa como si -1
estuviera dada.
Para trabajar con la idea con la que empezaste, debespodríausar eval
.
eval: eval [arg...]
Combine ARG en una sola cadena, use el resultado como entrada al shell y ejecute los comandos resultantes.
Pero el problema eval
es que todo lo que está en la línea de comando se analiza nuevamente, e incluso las cosas que normalmente son seguras, no lo son. Piense en un archivo llamado $(touch HELLO)
y qué sucede si un nombre como ese se coloca en la línea de comando.
Además, si sigue este camino, es posible que desee utilizar --quoting-style=shell
en lugar de, -Q
ya que puede coincidir más estrechamente con el procesamiento de los caracteres especiales por parte del shell. (Ambos pueden ser específicos de GNU ls, pero creo que -v
también lo son).
Respuesta3
Con zsh
, el (n)
calificador global le proporciona un orden de clasificación similar al de GNU ls -v
:
convert ./*.png(n) out.pdf
En un sistema GNU, con bash
, zsh
, yash
, mksh
o ksh93
:
eval "files=($(ls --quoting-style=shell-always -vd ./*.png))"
convert "${files[@]}" out.pdf
Respuesta4
Usando GNU Parallel se ve así:
ls -vd ./*png | parallel -Xj1 convert {} out.pdf