Tarez tous les PDF dans un répertoire, en conservant la structure du répertoire

11

J'essaie de créer une archive tar compressée qui contient tous les fichiers PDF qui existent dans l'un de mes répertoires. La structure du répertoire doit être conservée. Les répertoires vides ne sont pas nécessaires, mais je m'en fiche vraiment qu'ils soient là.

Par exemple, disons que j'avais un répertoire qui ressemblait à ceci:

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

Après avoir exécuté la commande, j'aimerais avoir dir.tar.gzceci:

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

Possible?

Matt Alexander
la source

Réponses:

10

Cela listera tous les PDF:

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

Vous pouvez diriger cela vers xargspour l'obtenir sous la forme d'une seule ligne délimitée par des espaces, et le nourrir tarpour créer l'archive:

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

(De cette façon, omet les répertoires vides)

Michael Mrozek
la source
1
C'est tellement génial, merci pour l'aide. Voici ce que j'ai trouvé:find docs \( -iname '*.pdf' -o -iname '*.mp3' \) -printf '"%p"\n' | xargs tar czf docs-media.tar.gz
Matt Alexander
3
@mattalexx: Attention, cette commande ne fonctionnera pas si l'un des noms de fichiers contient des espaces ou \'"(faute de xargs), et ne fonctionnera pas s'il y a trop de noms de fichiers (faute du noyau).
Gilles 'SO- arrête d'être méchant'
2
@Gilles En ce qui concerne les noms de fichiers avec des espaces et des guillemets simples, la -printf '"%p"\n'partie s'en occupe (du moins c'est ce que j'ai fait pour moi).
Matt Alexander
1
@Gilles Intéressant sur la restriction du noyau. Combien d'arguments pouvez-vous avoir dans une commande sous Linux?
Matt Alexander
5
Oh, sur le «ne fonctionnera pas», notez que le mode d'échec ici est que si la ligne de commande est trop longue, xargs la divisera, de sorte que la dernière invocation tar écrasera silencieusement les fichiers écrits par les invocations précédentes .
Gilles 'SO- arrête d'être méchant'
6

Avec bash ≥4 ou zsh et GNU tar:

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

Cela peut ne pas fonctionner si vous disposez d'un très grand nombre de fichiers PDF et que la ligne de commande est trop longue. Ensuite, vous auriez besoin d'une solution basée sur la recherche plus complexe (à nouveau, en utilisant GNU tar):

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

Alternativement (et de manière portable), vous pouvez créer l'archive avec pax .

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

Le premier -sdit d'inclure tous les .pdffichiers, sans changer leur nom. Le second -sdit de renommer tous les autres fichiers avec un nom vide, ce qui signifie en fait de ne pas les inclure dans l'archive.

Gilles 'SO- arrête d'être méchant'
la source
Oh ouais, je voulais parler des zsh **; Je ne savais même pas que bash 4 avait ça maintenant
Michael Mrozek