web-dev-qa-db-fra.com

Extraire plusieurs fichiers .tar.gz avec un seul appel tar

Je me demandais si (et, bien sûr, comment) il était possible de dire à tar d'extraire plusieurs fichiers en une seule fois.

Je suis un utilisateur expérimenté d'Unix depuis plusieurs années et bien sûr, je sais que vous pouvez utiliser for ou find ou des choses comme ça pour appeler tar une fois pour chaque archive que vous voulez pour extraire, mais je n'ai pas pu trouver une ligne de commande qui a provoqué mon tar pour extraire deux fichiers .tar.gz à la fois. (Et non, il n'y a rien de mal avec for, je demande simplement s'il est possible de s'en passer.)

Je pose cette question par curiosité, peut-être

  • il y a une étrange fourchette de tar quelque part qui prend en charge cette
  • quelqu'un sait comment utiliser le -M paramètre que tar m'a suggéré lorsque j'ai essayé tar -zxv -f a.tgz -f b.tgz
  • nous sommes tous aveugles et c'est très facile à faire - mais je n'ai trouvé aucun indice sur le Web qui n'ait pas utilisé for ou find ou xargs ou le comme.

Veuillez ne pas répondre avec tar -zxvf *.tar.gz (car cela ne fonctionne pas ) et ne répondez par "ne fonctionne pas" que si vous en êtes absolument sûr (et que vous avez peut-être un bonne explication pourquoi, aussi).

Edit: On m'a pointé ne réponse à cette question sur Stack Overflow qui dit en détail que ce n'est pas possible sans casser la syntaxe actuelle de tar, mais je ne pense pas que ce soit vrai. En utilisant tar -zxv -f a.tgz -f b.tgz ou tar -zxv --all-args-are-archives *.tar.gz ne briserait aucune syntaxe existante, à mon humble avis.

39
scy

C'est possible, la syntaxe est assez simple:

$ cat *.tar | tar -xvf - -i

L'option -i ignore le EOF à la fin des archives tar, depuis la page de manuel:

-i, --ignore-zeros
ignore blocks of zeros in archive (normally mean EOF)
43
polynomial

Pour *. Tar.gz:

for file in *.tar.gz; do tar -zxf "$file"; done

Pour *. Tar.bz2:

for file in *.tar.bz2; do tar -jxf "$file"; done

Pour *. Tar.xz:

for file in *.tar.xz; do tar -Jxf "$file"; done
29
Ratnesh

Vous devez utiliser une boucle. Cela ne briserait pas la syntaxe de ligne de commande tar pour autoriser plusieurs -f options, mais il faudrait ajouter du code pour traiter plusieurs archives en séquence, avec toutes sortes de conditions Edge (Que se passe-t-il si une archive au milieu est mal formée? Les archives peuvent-elles utiliser différents mécanismes de compression? Pouvez-vous avoir plusieurs -C options (option GNU tar pour extraire dans un répertoire particulier), aussi? Qu'en est--K (option tar GNU pour commencer à un certain nom de membre)? …).

Une possibilité d'éviter une boucle for est d'installer et d'activer AVFS , un système de fichiers Fuse qui fournit un accès transparent à les archives. Chaque archive /path/to/archive se double d'un répertoire ~/.avfs/path/to/archive#. Si vous voulez faire correspondre les archives avec des caractères génériques, il y a un obstacle à ajouter que # à une correspondance générique; cela peut être fait en zsh.

mountavfs
cp -p ~/.avfs$PWD/{a,b}.tgz\#/* /destination
cp -p ~/.avfs/path/to/source/*.tgz(e\''REPLY=$REPLY\#'\')/* /destination

find . -name "*.tar.gz" -exec tar xzf {} \;

0
zjengjie