2013-02-01 5 views

Antwort

13

Dies ist eine Möglichkeit, es

pdftk $(ls | sort -n) cat output combinewd2.pdf 

oder mit Graviszeichen

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

Wie dies zu tun, wird nicht funktionieren mit Leerzeichen auf Dateinamen in den Kommentaren darauf hingewiesen. In diesem Fall könnten Sie eval

eval pdftk $(while IFS= read -r file; do 
    echo \"$file\" 
done < <(ls | sort -n)) cat output combinewd2.pdf 

Angenommen, es den Namen „0 foo“ und „1 bar“ sind zwei Dateien zu verwenden, dann wäre das Ergebnis von eval der gewünschten Befehl sein, mit den Dateinamen in doppelten Anführungszeichen:

pdftk " 0 foo " " 1 bar " cat output combinewd2.pdf 

Wenn die Dateinamen möglicherweise Zeilenumbrüche enthalten, verwenden Sie den Befehl find, siehe die Diskussion von @joeytwiddle in den Kommentaren von @ andrewdotns Antwort. Die folgende Lösung ist auch für Dateinamen mit doppelten Anführungszeichen des sed Befehl doppelte Anführungszeichen zu entkommen:

eval pdftk $(while IFS= read -r -d '' file; do 
    echo \"$file\" 
done < <(find . -maxdepth 1 -type f -print0 | \ 
    sed 's/"/\\"/g'| sort -zn)) cat output combinewd2.pdf 
+2

Eine sehr 'bash' zentrierte Antwort, aber kühl dennoch. Dies funktioniert jedoch nicht in 'csh/tcsh'. (alle Kommentare zur Shell-Auswahl> '/ dev/null') – radical7

+0

Entscheidend ist, ** dies funktioniert nicht bei Dateinamen mit Leerzeichen **. Die Wörter werden in separate Argumente aufgeteilt. – joeytwiddle

+0

@joeytwiddle Sie sind richtig, ich schlage eine Lösung mit eval – amdn

8

Es ist hässlich, aber Sie können von xargs als "${@}", wie so sh -c und die Liste der Argumente übergeben laufen:

ls | sort -n | xargs -d'\n' sh -c 'pdftk "${@}" cat output combinewd2.pdf' "${0}" 

die zusätzliche "${0}" am Ende ist da, weil, wie die sh man page says

-cZeichenfolge

Wenn die -c Option vorhanden ist, werden dann Befehle von String lesen. Wenn nach der Zeichenfolge Argumente vorhanden sind, werden sie den Positionsparametern zugewiesen, beginnend mit $ 0.

Um dies zu testen, lassen Sie uns zunächst einige Dateien mit komplizierten Namen erstellen das wird vermasseln den meisten anderen Lösungen:

$ seq 1 100 | xargs -I{} touch '{} with "spaces"' 
$ ls 
1 with "spaces" 31 with "spaces" 54 with "spaces" 77 with "spaces" 
10 with "spaces" 32 with "spaces" 55 with "spaces" 78 with "spaces" 
100 with "spaces" 33 with "spaces" 56 with "spaces" 79 with "spaces" 
11 with "spaces" 34 with "spaces" 57 with "spaces" 8 with "spaces" 
12 with "spaces" 35 with "spaces" 58 with "spaces" 80 with "spaces" 
13 with "spaces" 36 with "spaces" 59 with "spaces" 81 with "spaces" 
14 with "spaces" 37 with "spaces" 6 with "spaces" 82 with "spaces" 
15 with "spaces" 38 with "spaces" 60 with "spaces" 83 with "spaces" 
16 with "spaces" 39 with "spaces" 61 with "spaces" 84 with "spaces" 
17 with "spaces" 4 with "spaces" 62 with "spaces" 85 with "spaces" 
18 with "spaces" 40 with "spaces" 63 with "spaces" 86 with "spaces" 
19 with "spaces" 41 with "spaces" 64 with "spaces" 87 with "spaces" 
2 with "spaces" 42 with "spaces" 65 with "spaces" 88 with "spaces" 
20 with "spaces" 43 with "spaces" 66 with "spaces" 89 with "spaces" 
21 with "spaces" 44 with "spaces" 67 with "spaces" 9 with "spaces" 
22 with "spaces" 45 with "spaces" 68 with "spaces" 90 with "spaces" 
23 with "spaces" 46 with "spaces" 69 with "spaces" 91 with "spaces" 
24 with "spaces" 47 with "spaces" 7 with "spaces" 92 with "spaces" 
25 with "spaces" 48 with "spaces" 70 with "spaces" 93 with "spaces" 
26 with "spaces" 49 with "spaces" 71 with "spaces" 94 with "spaces" 
27 with "spaces" 5 with "spaces" 72 with "spaces" 95 with "spaces" 
28 with "spaces" 50 with "spaces" 73 with "spaces" 96 with "spaces" 
29 with "spaces" 51 with "spaces" 74 with "spaces" 97 with "spaces" 
3 with "spaces" 52 with "spaces" 75 with "spaces" 98 with "spaces" 
30 with "spaces" 53 with "spaces" 76 with "spaces" 99 with "spaces" 
$ ls | sort -n | xargs -d'\n' sh -c 'set -x; pdftk "${@}" cat output combinewd2.pdf' "${0}" 
+ pdftk '1 with "spaces"' '2 with "spaces"' '3 with "spaces"' '4 with "spaces"' '5 with "spaces"' '6 with "spaces"' '7 with "spaces"' '8 with "spaces"' '9 with "spaces"' '10 with "spaces"' '11 with "spaces"' '12 with "spaces"' '13 with "spaces"' '14 with "spaces"' '15 with "spaces"' '16 with "spaces"' '17 with "spaces"' '18 with "spaces"' '19 with "spaces"' '20 with "spaces"' '21 with "spaces"' '22 with "spaces"' '23 with "spaces"' '24 with "spaces"' '25 with "spaces"' '26 with "spaces"' '27 with "spaces"' '28 with "spaces"' '29 with "spaces"' '30 with "spaces"' '31 with "spaces"' '32 with "spaces"' '33 with "spaces"' '34 with "spaces"' '35 with "spaces"' '36 with "spaces"' '37 with "spaces"' '38 with "spaces"' '39 with "spaces"' '40 with "spaces"' '41 with "spaces"' '42 with "spaces"' '43 with "spaces"' '44 with "spaces"' '45 with "spaces"' '46 with "spaces"' '47 with "spaces"' '48 with "spaces"' '49 with "spaces"' '50 with "spaces"' '51 with "spaces"' '52 with "spaces"' '53 with "spaces"' '54 with "spaces"' '55 with "spaces"' '56 with "spaces"' '57 with "spaces"' '58 with "spaces"' '59 with "spaces"' '60 with "spaces"' '61 with "spaces"' '62 with "spaces"' '63 with "spaces"' '64 with "spaces"' '65 with "spaces"' '66 with "spaces"' '67 with "spaces"' '68 with "spaces"' '69 with "spaces"' '70 with "spaces"' '71 with "spaces"' '72 with "spaces"' '73 with "spaces"' '74 with "spaces"' '75 with "spaces"' '76 with "spaces"' '77 with "spaces"' '78 with "spaces"' '79 with "spaces"' '80 with "spaces"' '81 with "spaces"' '82 with "spaces"' '83 with "spaces"' '84 with "spaces"' '85 with "spaces"' '86 with "spaces"' '87 with "spaces"' '88 with "spaces"' '89 with "spaces"' '90 with "spaces"' '91 with "spaces"' '92 with "spaces"' '93 with "spaces"' '94 with "spaces"' '95 with "spaces"' '96 with "spaces"' '97 with "spaces"' '98 with "spaces"' '99 with "spaces"' '100 with "spaces"' cat output combinewd2.pdf 

Alle Argumente korrekt angegeben sind. Beachten Sie, dass dies fehlschlägt, wenn alle Dateinamen Zeilenumbrüche enthalten und dass ls -v im Grunde ls | sort -n ist.Dies sollte mit Leerzeichen, Zeilenumbrüche, Apostrophe und Anführungszeichen auf Dateinamen arbeiten (die alle auf UNIX-Dateisysteme sind möglich)

+0

Dies funktioniert bei Dateinamen, die Leerzeichen enthalten, nicht jedoch bei Dateinamen, die Zeilenumbrüche enthalten. Obwohl diese nicht sehr häufig sind, können sie richtig gehandhabt werden mit: 'finden. -type f -maxdepth 1 -print0 | sortieren -zn | xargs -0 sh -c ... ' – joeytwiddle

+0

Obwohl, wenn wir' find' verwenden, dann brauchen wir 'xargs' überhaupt nicht! Wir können 'find ... -exec [command] {} +' verwenden, wie in [BashFAQ/020] empfohlen (http://mywiki.wooledge.org/BashFAQ/020). – joeytwiddle

+0

@joeytwiddle Yup, benutze 'find' anstelle von' ls' wenn es neue Zeilen in Dateinamen geben könnte. – andrewdotn

2

:

find . -maxdepth 1 -type f -print0 | 
    sort -zn | 
    xargs -0 sh -c 'pdftk "[email protected]" cat output combinewd2.pdf' "$0" 

Das könnte viel des Guten auf die akzeptierte Antwort verglichen werden, wenn Sie wissen, arbeiten mit einfachen Dateinamen.

Aber wenn Sie ein Skript schreiben, das in Zukunft wieder verwendet wird, ist es wünschenswert, dass es eines Tages nicht explodiert, wenn es ungewöhnliche (aber gültige) Eingaben trifft.

Dies ist im Grunde eine Anpassung der andrewdotn 's Antwort, die Eingabedateien mit einem Null-Byte statt mit einem Zeilenumbruch beendet, daher Dateinamen beibehalten, die ein oder mehrere Zeilenumbruchzeichen enthalten.

Die jeweiligen Optionen -print0, -z und -0 teilen jedem Programm mit, dass die Ein-/Ausgabe durch das Nullbyte begrenzt werden soll. Drei verschiedene Programme, drei verschiedene Argumente!

0

Das Problem hier ist, dass während Xargs einzelne Argumente in der Mitte des Befehls mit -i und {} setzen kann, weigert es sich, dies für mehrere Argumente zu tun. Das scheint ein Versehen zu sein, das uns viele Probleme bereitet!

Abgesehen von den obigen Lösungen besteht eine andere Alternative darin, einfach die Argumente hinzuzufügen, die nach den Dateien an das Ende der Liste der Dateien kommen sollen.

(
    ls | sort -n 
    echo cat 
    echo output 
    echo combinewd2.pdf 
) | xargs -d'\n' pdftk 

Dieser Ansatz funktioniert nicht auf Dateinamen mit Zeilenumbrüchen. Für diesen seltenen Fall sollten Sie Zeilen, die mit einem Nullbyte abgeschlossen sind, an xargs übergeben, wie es in meiner anderen Antwort angeboten wird.

8

Verwenden -I Option:

echo prefix | xargs -I % echo % post 

Ausgang:

prefix post 
+1

Dies funktioniert jedoch nicht wie gewünscht (es ruft den Befehl dreimal auf, statt einmal mit drei Argumenten), wenn Sie Verwenden Sie "ls" anstatt "echo" als Eingabe, was das OP versucht zu tun ... – DNA