2013-02-01 10 views

risposta

13

questo è un modo per farlo

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

o utilizzando backtick

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

Come sottolineato nei commenti questo non funzionerà su nomi di file contenenti spazi. In questo caso è possibile utilizzare eval

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

Supponiamo che ci siano due file denominati "0 pippo" e "1 bar" allora il risultato di eval sarebbe il comando desiderato, con i nomi dei file tra virgolette:

Se il nome file può contenere righe nuove, utilizzare il comando find, vedere la discussione di @joeytwiddle nei commenti della risposta di @ andrewdotn. La seguente soluzione gestisce anche i nomi di file con doppi apici utilizzando il comando sed per sfuggire le virgolette doppie:

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

Un 'risposta molto bash'-centrica, ma fresco comunque. Ciò non funzionerà in 'csh/tcsh', comunque. (tutti i commenti sulla scelta della shell> '/ dev/null') – radical7

+0

In modo cruciale, ** questo non funzionerà su nomi di file contenenti spazi **. Le parole saranno suddivise in argomenti separati. – joeytwiddle

+0

@joeytwiddle hai ragione, propongo una soluzione usando eval – amdn

8

E 'brutto, ma è possibile eseguire sh -c e accedere alla lista di argomenti passati da xargs come "${@}", in questo modo:

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

l'extra "${0}" alla fine è lì perché, come il sh man page says

-cstringa

Se l'opzione -c è presente, allora i comandi sono letti da stringa. Se sono presenti argomenti dopo la stringa , vengono assegnati ai parametri posizionali, a partire da $ 0.

Per verificare ciò, si deve prima creare alcuni file con nomi complicati che saranno rovinare 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 in modo corretto. Notare che ciò non riuscirà se tutti i nomi di file contengono newline e che ls -v è fondamentalmente ls | sort -n.

+0

Funziona su nomi di file che contengono spazi, ma non su nomi di file che contengono righe nuove. Anche se questi non sono molto comuni, possono essere gestiti correttamente con: 'find. -tipo f -maxdepth 1 -print0 | ordina -zn | xargs -0 sh -c ... ' – joeytwiddle

+0

Anche se usiamo' find', non abbiamo bisogno di 'xargs'! Possiamo usare 'find ... -exec [comando] {} +' come raccomandato in [BashFAQ/020] (http://mywiki.wooledge.org/BashFAQ/020). – joeytwiddle

+0

@joeytwiddle Yup, usa 'find' invece di' ls' se potrebbero esserci nuove righe nei nomi dei file. – andrewdotn

2

Questo dovrebbe funzionare su nomi di file contenenti spazi, a capo, apostrofi e le virgolette (che sono tutti possibili su file system UNIX):

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

che potrebbe essere eccessivo rispetto alla risposta accettata, se si conosce stanno lavorando con nomi di file semplici.

Ma se si sta scrivendo uno script che verrà riutilizzato in futuro, è auspicabile che non esploda un giorno quando incontra input insoliti (ma validi).

Si tratta fondamentalmente di un adattamento della risposta di andrewdotn che termina i file di input con un byte zero, anziché 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 raccontano ciascuno dei programmi che l'input/output deve essere delimitata dal byte zero. Tre programmi diversi, tre argomenti diversi!

0

Il problema è che mentre gli xarg possono inserire singoli argomenti nel mezzo del comando con -i e {}, si rifiuta di farlo per più argomenti. Questa sembra essere una svista che finisce per causarci un sacco di problemi!

Oltre alle soluzioni sopra, un'altra alternativa è semplicemente aggiungere gli argomenti che si desidera vengano dopo i file alla fine dell'elenco di file.

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

Questo approccio non funziona su nomi di file contenenti ritorni a capo. In quel raro caso dovresti passare le righe terminate con un byte zero a xargs, come offerto nella mia altra risposta.

8

Uso -I opzione:

echo prefix | xargs -I % echo % post 

uscita:

prefix post 
+1

Tuttavia, questo non funziona come desiderato (chiama il comando tre volte, piuttosto che una volta con tre argomenti) se tu usa 'ls' piuttosto che' echo' come input, che è ciò che l'OP sta cercando di fare ... – DNA

Problemi correlati