Verwenden Sie -I
Möglichkeit:
echo prefix | xargs -I % echo % post
Ausgabe:
prefix post
Dies ist eine Möglichkeit, dies zu tun
pdftk $(ls | sort -n) cat output combinewd2.pdf
oder mit Backtick
pdftk `ls | sort -n` cat output combinewd2.pdf
Wenn die Dateinamen beispielsweise 100, 2, 9, 3.14, 10, 1 lauten, lautet der Befehl
pdftk 1 2 3.14 9 10 100 cat output combinewd2.pdf
Um Dateinamen mit Leerzeichen oder anderen Sonderzeichen zu handhaben, betrachten Sie dies als behoben Version von @joeytwiddles ausgezeichnet Antwort (die nicht numerisch sortiert, siehe Diskussion unten):
#-- The following will handle special characters, and
# will sort filenames numerically
# e.g. filenames 100, 2, 9, 3.14, 10, 1 results in
# ./1 ./2 ./3.14 ./9 ./10 ./100
#
find . -maxdepth 1 -type f -print0 |
sort -k1.3n -z -t '\0' |
xargs -0 sh -c 'pdftk "[email protected]" cat output combinewd2.pdf' "$0"
Alternativen zu xargs (Bash-spezifisch)
xargs
ist ein externer Befehl, im vorherigen Beispiel ruft er sh
auf was wiederum pdftk
aufruft .
Eine Alternative ist die Verwendung des eingebauten mapfile
falls verfügbar, oder verwenden Sie die Positionsparameter. Die folgenden Beispiele verwenden zwei Funktionen, print0_files generiert die NUL-terminierten Dateinamen und create_pdf ruft pdftk
auf :
print0_files | create_pdf combinewd2.pdf
Die Funktionen sind wie folgt definiert
#-- Generate the NUL terminated filenames, numerically sorted
print0_files() {
find . -maxdepth 1 -type f -print0 |
sort -k1.3n -z -t '\0'
}
#-- Read NUL terminated filenames using mapfile
create_pdf() {
mapfile -d ''
pdftk "${MAPFILE[@]}" cat output "$1"
}
#-- Alternative using positional parameters
create_pdf() {
local -r pdf=$1
set --
while IFS= read -r -d '' f; do set -- "[email protected]" "$f"; done
pdftk "[email protected]" cat output "$pdf"
}
Diskussion
Wie in den Kommentaren erwähnt, funktioniert die einfache anfängliche Antwort nicht mit Dateinamen, die Leerzeichen oder andere Sonderzeichen enthalten. Die Antwort von @joeytwiddle verarbeitet Sonderzeichen, obwohl sie nicht numerisch sortiert
#-- The following will not sort numerically due to ./ prefix,
# e.g. filenames 100, 2, 9, 3.14, 10, 1 results in
# ./1 ./10 ./100 ./2 ./3.14 ./9
#
find . -maxdepth 1 -type f -print0 |
sort -zn |
xargs -0 sh -c 'pdftk "[email protected]" cat output combinewd2.pdf' "$0"
Es wird nicht numerisch sortiert, da jedem Dateinamen ./
vorangestellt ist durch die find
Befehl. Einige Versionen von find
Befehlsunterstützung -printf '%P\0'
was den ./
nicht enthalten würde Präfix. Eine einfachere, portable Lösung besteht darin, -d, --dictionary-order
hinzuzufügen Option zum sort
Befehl so, dass er bei Vergleichen nur Leerzeichen und alphanumerische Zeichen berücksichtigt, aber trotzdem die falsche Reihenfolge erzeugen kann
#-- The following will not sort numerically due to decimals
# e.g. filenames 100, 2, 9, 3.14, 10, 1 results in
# ./1 ./2 ./9 ./10 ./100 ./3.14
#
find . -maxdepth 1 -type f -print0 |
sort -dzn |
xargs -0 sh -c 'pdftk "[email protected]" cat output combinewd2.pdf' "$0"
Wenn Dateinamen Dezimalstellen enthalten, kann dies zu einer falschen numerischen Sortierung führen. Die sort
Der Befehl erlaubt beim Sortieren einen Offset in ein Feld, sort -k1.3n
, muss man allerdings bei der Definition des Feldtrenners aufpassen, wenn Dateinamen möglichst allgemein gehalten werden sollen, zum Glück sort -t '\0'
gibt NUL als Feldtrennzeichen und den find -print0
an Option gibt an, dass NUL als Trennzeichen zwischen Dateinamen verwendet werden soll, also sort -z -t '\0'
gibt NUL sowohl als Datensatzbegrenzer als auch als Feldtrennzeichen an – jeder Dateiname ist dann ein einzelner Felddatensatz. In Anbetracht dessen können wir dann in das einzelne Feld versetzt werden und den ./
überspringen Präfix durch Angabe des 3. Zeichens des 1. Feldes als Startposition für die numerische Sortierung, sort -k1.3n -z -t '\0'
.
Dies sollte bei Dateinamen funktionieren, die Leerzeichen, Zeilenumbrüche, Apostrophe und Anführungszeichen enthalten (die alle auf UNIX-Dateisystemen möglich sind):
find . -maxdepth 1 -type f -print0 |
sort -zn |
xargs -0 sh -c 'pdftk "[email protected]" cat output combinewd2.pdf' "$0"
Das könnte im Vergleich zur akzeptierten Antwort übertrieben sein, wenn Sie wissen, dass Sie mit einfachen Dateinamen arbeiten.
Aber wenn Sie ein Skript schreiben, das in Zukunft wieder verwendet wird, ist es wünschenswert, dass es nicht eines Tages explodiert, wenn es auf ungewöhnliche (aber gültige) Eingaben trifft.
Dies ist im Grunde eine Anpassung von Andrewdotns Antwort, die Eingabedateien mit einem Null-Byte statt mit einem Zeilenumbruch abschließt, wodurch Dateinamen erhalten bleiben, die ein oder mehrere Zeilenumbruchzeichen enthalten.
Die jeweiligen Optionen -print0
, -z
und -0
Teilen Sie jedem der Programme mit, dass die Ein-/Ausgabe durch das Null-Byte begrenzt werden soll. Drei verschiedene Programme, drei verschiedene Argumente!
Es ist hässlich, aber Sie können sh -c
ausführen und auf die Liste der von xargs
übergebenen Argumente zugreifen als "${@}"
, etwa so:
ls | sort -n | xargs -d'\n' sh -c 'pdftk "${@}" cat output combinewd2.pdf' "${0}"
Das zusätzliche "${0}"
am ende steht da da, als sh
Manpage sagt
-c Zeichenfolge
Wenn das -c Option vorhanden ist, dann werden Befehle aus String gelesen . Wenn hinter dem String Argumente stehen , werden sie den Positionsparametern zugewiesen, beginnend mit $0 .
Um dies zu testen, erstellen wir zunächst einige Dateien mit komplizierten Namen, die die meisten anderen Lösungen durcheinander bringen:
$ 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 sind korrekt zitiert. Beachten Sie, dass dies fehlschlägt, wenn Dateinamen Zeilenumbrüche enthalten, und dass ls -v
ist im Grunde ls | sort -n
.