web-dev-qa-db-fra.com

tar - extraire la structure du répertoire de rejet

unzip a une option astucieuse -j, grâce à laquelle la structure de répertoires de l'archive est supprimée et tous les fichiers sont extraits dans le même répertoire.

Existe-t-il un moyen de faire fonctionner tar de la même manière? Rien dans la page de manuel ne semble l'indiquer.

Donc, existe-t-il un outil alternatif, de préférence logiciel libre, pour le faire?

34
Benji XVI

Le goudron GNU vit sur les caractéristiques, il existe donc naturellement des options pour cela.
http://www.gnu.org/software/tar/manual/html_node/transform.html

Si vous voulez seulement supprimer quelques segments de chemin, alors --strip-components=n ou --strip=n fera souvent:

 tar xvzf tgz --strip=1

Mais il est également possible de réécrire de manière régulière les fichiers à extraire (les drapeaux sont --transform ou --xform et accepter ereg avec le modificateur /x):

 tar xvzf tgz --xform='s#^[^/]+#.#x'
                 # or 's#^.+/##x' for discarding all paths

Pour lister un tar, vous avez besoin de l'option --show-transformed supplémentaire:

 tar tvzf tgz --show-transformed --strip=1 --xform='s/abc/xyz/x'

Je crois que les options de réécriture fonctionnent également pour l’emballage, pas seulement pour l’extraction. Mais pax a évidemment une syntaxe plus agréable.

74
mario

Vous pouvez le faire assez facilement en deux étapes. Adapter si nécessaire:

$ mkdir /tmp/dirtree
$ tar xfz /path/to/archive -C /tmp/dirtree
$ find /tmp/dirtree -type f -exec mv -i {} . \;
$ rm -rf /tmp/dirtree
13
MikeyB

pax peut le faire:

pax -v -r -s '/.*\///p' < archive.tar

ou

zcat archive.tar.gz | pax -v -r -s '/.*\///p'

Vous pouvez d'abord vérifier l'opération de remplacement de nom en omettant l'option -r.

8
hfs

Une solution possible qui ne nécessite aucune installation.

  1. utilisez un tar tvf pour récupérer tous les fichiers de l'archive
  2. Extrayez ces fichiers individuellement - extrayez tar à stdout et redirigez-le à $ filename

    tar -tvf $1 | grep -v "^d" | \
                  awk '{for(i=6;i<NF+1;i++) {printf "%s ",$i};print ""}' |\
                  while read filename
                  do
                     tar -O -xf $1 "$filename" > `basename "$filename"`
                  done
    

enregistrer en tant que extract.sh et exécuter en tant que extract.sh myfile.tar. Il écrasera également les noms de fichiers en double rencontrés dans les répertoires extraits de l'archive.

1
DaveParillo