Tarare tutti i PDF in una directory, mantenendo la struttura della directory


11

Sto cercando di creare un tarball compresso che contiene tutti i file PDF presenti in una delle mie directory. La struttura della directory deve essere mantenuta. Le directory vuote non sono necessarie, ma non mi interessa davvero se sono lì.

Ad esempio, supponiamo che avessi una directory simile a questa:

dir
dir/subdir1
dir/subdir1/subsubdir1/song.mp3
dir/subdir2
dir/subdir2/subsubdir1
dir/subdir2/subsubdir1/document.pdf
dir/subdir2/subsubdir1/another-song.mp3
dir/subdir2/subsubdir1/top-ten-movies.txt
dir/subdir3
dir/subdir3/another-document.pdf

Dopo aver eseguito il comando, vorrei dir.tar.gzcontenere questo:

dir
dir/subdir2
dir/subdir2/subsubdir1
dir/subdir2/subsubdir1/document.pdf
dir/subdir3
dir/subdir3/another-document.pdf

Possibile?

Risposte:


10

Questo elencherà tutti i PDF:

$ find dir/ -name '*.pdf'
./dir/subdir2/subsubdir1/document.pdf
./dir/subdir3/another-document.pdf

Puoi reindirizzarlo xargsper ottenerlo come una singola linea delimitata da spazi e alimentarlo tarper creare l'archivio:

$ find dir/ -name '*.pdf' | xargs tar czf dir.tar.gz

(In questo modo omette le directory vuote)


1
È fantastico, grazie per l'aiuto. Ecco cosa mi è venuto in mente:find docs \( -iname '*.pdf' -o -iname '*.mp3' \) -printf '"%p"\n' | xargs tar czf docs-media.tar.gz
Matt Alexander

3
@mattalexx: attenzione che questo comando non funzionerà se uno dei nomi dei file contiene spazi o \'"(colpa di xargs) e non funzionerà se ci sono troppi nomi di file (colpa del kernel).
Gilles 'SO- smetti di essere cattivo' il

2
@Gilles Per quanto riguarda i nomi di file con spazi e virgolette singole, la -printf '"%p"\n'parte se ne occupa (almeno per me).
Matt Alexander

1
@Gilles Interessante per la restrizione del kernel. Quanti argomenti puoi avere in un comando in Linux?
Matt Alexander

5
Oh, sul "non funzionerà", si noti che la modalità di errore qui è che se la riga di comando è troppo lunga, xargs lo dividerà, in modo che l'ultima chiamata di tar sovrascriva silenziosamente i file scritti da precedenti invocazioni .
Gilles 'SO- smetti di essere cattivo' il

6

Con bash ≥4 o zsh e GNU tar:

tar -czf dir.tar.gz dir/**/*.pdf

Questo potrebbe non funzionare se si dispone di un numero molto elevato di file PDF e la riga di comando è troppo lunga. Quindi avresti bisogno di una soluzione basata su find più complessa (di nuovo, usando GNU tar):

tar -cf dir.tar -T /dev/null
find dir -name '*.pdf' -exec tar -rf dir.tar {} +
gzip dir.tar

In alternativa (e portabile) è possibile creare l'archivio con pax .

pax -w -x ustar -s '/\.pdf$/&/' -s '/.*//' . | gzip >dir.tar.gz

Il primo -sdice di includere tutti i .pdffile, senza cambiare il loro nome. Il secondo -sdice di rinominare tutti gli altri file con un nome vuoto, il che significa in realtà non includerli nell'archivio.


Oh sì, intendevo menzionare gli zsh **; Non avevo nemmeno realizzato che bash 4 ce l'avesse adesso
Michael Mrozek
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.