
Ich möchte einige PNG-Dateien zu einem PDF zusammenfügen. Der Befehl
convert *png out.pdf
funktioniert, aber die Reihenfolge ist falsch. Es stellt sich heraus, dass
ls -v *png
ergibt die gewünschte Reihenfolge, daher möchte ich die Ausgabe zur Konvertierung weitergeben.
Ich habe versucht
convert `ls -v *png` out.pdf
Dies funktioniert jedoch nicht, da die Dateinamen Leerzeichen und Klammern enthalten.
Anweisungen ls
zum Setzen der Dateinamen in Anführungszeichen über
convert `ls -vQ *png` out.pdf
funktioniert auch nicht, da die Anführungszeichen bei der Ersetzung entfernt zu werden scheinen.
Was kann ich machen?
Antwort1
Wenn Sie ein aktuelles GNU-basiertes System haben (das sort
eine ähnliche -V
Sortierung in der natürlichen Version bietet), können Sie damit sortieren und das Ergebnis in ein Array einlesen:
while read -rd '' f; do
files+=("$f")
done < <(find . -maxdepth 1 -name '*png' -print0 | sort -zV)
Dann sollten Sie in der Lage sein, das Array innerhalb Ihres convert
Befehls zu erweitern:
convert "${files[@]}" out.pdf
Antwort2
Wenn Ihre Dateinamen keine Zeilenumbrüche enthalten, können Sie dies möglicherweise tun, indem Sie der Shell sagen, dass die Ausgabe ls
nur bei Zeilenumbrüchen und nicht bei Leerzeichen aufgeteilt werden soll. DieSpaltungwird durch die Variable gesteuert IFS
, alle darin enthaltenen Zeichen IFS
werden als Trennzeichen verwendet.
IFS=$'\n' # set it to just a newline
convert $(ls -vd ./*.png) output.pdf
Dies kann immer noch Probleme bereiten, wenn die Dateinamen merkwürdig genug sind oder wenn ls
sie für die Anzeige verstümmelt werden. Beim Drucken auf einem Terminal ls
listet es die Dateien normalerweise in mehreren Spalten auf. Aber wenn die Ausgabe nicht an ein Terminal geht (hier liest die Shell sie), verhält es sich so, als ob sie -1
ausgegeben worden wäre.
Um mit der Idee zu arbeiten, mit der Sie begonnen haben,könnteverwenden eval
.
eval: eval [arg ...]
Kombinieren Sie ARGs in einer einzigen Zeichenfolge, verwenden Sie das Ergebnis als Eingabe für die Shell und führen Sie die resultierenden Befehle aus.
Das Problem dabei eval
ist jedoch, dass alles und jedes in der Befehlszeile erneut analysiert wird, und selbst Dinge, die normalerweise sicher sind, werden nicht analysiert. Denken Sie an eine Datei mit dem Namen $(touch HELLO)
und was passiert, wenn ein solcher Name in die Befehlszeile eingefügt wird.
--quoting-style=shell
Wenn Sie diesen Weg wählen, möchten Sie möglicherweise auch anstelle von verwenden, -Q
da dies der Verarbeitung der Sonderzeichen durch die Shell möglicherweise besser entspricht. (Beide sind möglicherweise spezifisch für GNU ls, aber ich denke -v
, das ist es auch.)
Antwort3
Mit erhalten Sie durch zsh
den (n)
Glob-Qualifizierer eine ähnliche Sortierreihenfolge wie bei GNU ls -v
:
convert ./*.png(n) out.pdf
Auf einem GNU-System mit bash
, zsh
, yash
, mksh
oder ksh93
:
eval "files=($(ls --quoting-style=shell-always -vd ./*.png))"
convert "${files[@]}" out.pdf
Antwort4
Mit GNU Parallel sieht es folgendermaßen aus:
ls -vd ./*png | parallel -Xj1 convert {} out.pdf