Usa -I
opzione:
echo prefix | xargs -I % echo % post
Uscita:
prefix post
Questo è un modo per farlo
pdftk $(ls | sort -n) cat output combinewd2.pdf
o usando il backtick
pdftk `ls | sort -n` cat output combinewd2.pdf
Ad esempio, se i nomi dei file sono 100, 2, 9, 3.14, 10, 1 il comando sarà
pdftk 1 2 3.14 9 10 100 cat output combinewd2.pdf
Per gestire i nomi di file con spazi o altri caratteri speciali, considera questo risolto versione di eccellente di @joeytwiddle risposta (che non ordina numericamente, vedi discussione sotto):
#-- 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"
Alternative a xargs (specifiche per bash)
xargs
è un comando esterno, nell'esempio precedente invoca sh
che a sua volta invoca pdftk
.
Un'alternativa è usare l'integrato mapfile
se disponibile, o utilizzare i parametri posizionali. Gli esempi seguenti utilizzano due funzioni, print0_files genera i nomi file con terminazione NUL e create_pdf invoca pdftk
:
print0_files | create_pdf combinewd2.pdf
Le funzioni sono definite come segue
#-- 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"
}
Discussione
Come sottolineato nei commenti, la semplice risposta iniziale non funziona con nomi di file contenenti spazi o altri caratteri speciali. La risposta di @joeytwiddle gestisce i caratteri speciali, anche se non ordina numericamente
#-- 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"
Non ordina numericamente poiché ciascun nome di file è preceduto da ./
dal find
comando. Alcune versioni del find
supporto comando -printf '%P\0'
che non includerebbe il ./
prefisso. Una soluzione più semplice e portatile consiste nell'aggiungere il -d, --dictionary-order
opzione al sort
comando in modo che consideri solo spazi vuoti e caratteri alfanumerici nei confronti, ma potrebbe comunque produrre un ordinamento errato
#-- 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"
Se i nomi dei file contengono decimali, ciò potrebbe causare un ordinamento numerico errato. Il sort
Il comando consente un offset in un campo durante l'ordinamento, sort -k1.3n
, però bisogna fare attenzione nel definire il separatore di campo se i nomi dei file devono essere il più generici possibile, fortunatamente sort -t '\0'
specifica NUL come separatore di campo e find -print0
l'opzione indica che NUL deve essere usato come delimitatore tra i nomi dei file, quindi sort -z -t '\0'
specifica NUL sia come delimitatore di record che come separatore di campo:ogni nome di file è quindi un singolo record di campo. Detto questo, possiamo quindi eseguire l'offset nel campo singolo e saltare il ./
prefisso specificando il 3° carattere del 1° campo come posizione iniziale per l'ordinamento numerico, sort -k1.3n -z -t '\0'
.
Questo dovrebbe funzionare su nomi di file contenenti spazi, newline, apostrofi e virgolette (tutti possibili su filesystem UNIX):
find . -maxdepth 1 -type f -print0 |
sort -zn |
xargs -0 sh -c 'pdftk "[email protected]" cat output combinewd2.pdf' "$0"
Potrebbe essere eccessivo rispetto alla risposta accettata, se sai che stai lavorando con nomi di file semplici.
Ma se stai scrivendo uno script che verrà riutilizzato in futuro, è auspicabile che non esploda un giorno quando incontra input insoliti (ma validi).
Questo è fondamentalmente un adattamento della risposta di andrewdotn che termina i file di input con un byte zero, invece che con una nuova riga, preservando quindi i nomi di file che contengono uno o più caratteri di nuova riga.
Le rispettive opzioni -print0
, -z
e -0
dire a ciascuno dei programmi che l'input/output dovrebbe essere delimitato dal byte zero. Tre programmi diversi, tre argomenti diversi!
È brutto, ma puoi eseguire sh -c
e accedi all'elenco degli argomenti passati da xargs
come "${@}"
, in questo modo:
ls | sort -n | xargs -d'\n' sh -c 'pdftk "${@}" cat output combinewd2.pdf' "${0}"
Il "${0}"
in più alla fine c'è perché, come dice il sh
dice la pagina man
-c stringa
Se -c è presente l'opzione, i comandi vengono letti da stringa . Se ci sono argomenti dopo la stringa , vengono assegnati ai parametri posizionali, a partire da $0 .
Per verificarlo, creiamo prima alcuni file con nomi complicati che rovineranno la maggior parte delle altre soluzioni:
$ 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
Tutti gli argomenti sono citati correttamente. Nota che questo fallirà se qualche nome di file contiene caratteri di nuova riga e che ls -v
è fondamentalmente ls | sort -n
.