Problem beim Zitieren der ls-Ausgabe

Problem beim Zitieren der ls-Ausgabe

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 lszum 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 sorteine ähnliche -VSortierung 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 convertBefehls 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 lsnur bei Zeilenumbrüchen und nicht bei Leerzeichen aufgeteilt werden soll. DieSpaltungwird durch die Variable gesteuert IFS, alle darin enthaltenen Zeichen IFSwerden 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 lssie für die Anzeige verstümmelt werden. Beim Drucken auf einem Terminal lslistet 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 -1ausgegeben 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 evalist 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=shellWenn Sie diesen Weg wählen, möchten Sie möglicherweise auch anstelle von verwenden, -Qda 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 zshden (n)Glob-Qualifizierer eine ähnliche Sortierreihenfolge wie bei GNU ls -v:

convert ./*.png(n) out.pdf

Auf einem GNU-System mit bash, zsh, yash, mkshoder 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

verwandte Informationen