4 votes

Déballer une tarball via le terminal comme avec le Finder

Si j'ai un fichier .tar ou .tgz ou .tbz sur mon bureau, et que je double-clique dessus, je trouve le dossier qui a été compressé, soigneusement décompressé juste à côté du fichier d'archive. Exactement comme vous vous y attendriez.

Lorsque j'essaie de décompresser un élément taré via la commande tar, la sortie que j'obtiens contient tout le chemin complet du fichier compressé d'origine.

Donc, par exemple, si je crée un fichier .tbz à partir d'un dossier sur mon bureau appelé "foo", et que je le décompresse via tar -xf foo.tbz ~/Bureau/foo, ce que j'obtiens est : /Utilisateurs/[utilisateur]/Bureau/foo/Utilisateurs/[utilisateur]/bureau/foo/bar.txt

Y a-t-il un drapeau magique dans tar que je ne vois pas? J'ai cherché des 'comment faire' après des 'comment faire' qui vous donnent une simple commande tar pour extraire un fichier, mais toutes les directions que je vois me donnent mon résultat indésiré avec des répertoires longs, inutiles et superposés.

2voto

jaume Points 13186

L'option que vous recherchez est --strip-components (à partir de man tar) :

--strip-components compte

(mode x uniquement) Supprime le nombre spécifié d'éléments de chemin en tête. Les noms de chemin avec moins d'éléments seront ignorés silencieusement.

Mais ce n'est pas totalement équivalent à la manière dont fonctionne le Finder : vous devez encore connaître la profondeur du répertoire à supprimer.

Heureusement, cela peut être calculé avec cette commande :

while read; do echo -n "$REPLY" | wc -c; done < <(tar tvf  | egrep -v '^d' | sed 's:[^/]::g') | sort -n | uniq | head -n 1

Comme vous devez remplacer par le nom de votre archive tar, ce n'est pas aussi pratique que simplement double-cliquer dessus dans le Finder, mais cela peut être utile dans les scripts Bash.

Si l'archive tar contient plusieurs fichiers dans des chemins différents, la commande ci-dessus calcule la profondeur de répertoire commune maximale :

contenu de l'archive tar          =>      fichiers extraits en utilisant --strip-components

dir1/dir2/file1               =>      file1
dir1/dir2/dir3/file2          =>      dir3/file2
dir1/dir2/dir3/dir4/file3     =>      dir3/dir4/file3

Par exemple, si vous créez un fichier tar de cette manière :

mkdir -p a/b/c/d/e/f
touch a/b/c/d/e/f/myfile1
touch a/b/c/d/e/myfile2
tar cvf file.tar a

de sorte que :

tar tf file.tar
a/
a/b/
a/b/c/
a/b/c/d/
a/b/c/d/e/
a/b/c/d/e/f/
a/b/c/d/e/myfile1
a/b/c/d/e/f/myfile2

vous pouvez extraire tous les fichiers (avec une profondeur de répertoire minimale) de la manière suivante :

  1. Calculer la profondeur de répertoire commune maximale :

    while read; do echo -n "$REPLY" | wc -c; done < <(tar tvf file.tar | egrep -v '^d' | sed 's:[^/]::g') | sort -n | uniq | head -n 1

    La commande retourne 5.

  2. Exécuter tar en passant le résultat de la commande précédente à --strip-components :

    tar xvf file.tar --strip-components 5
    x f/
    x myfile1
    x f/myfile2

Au lieu d'exécuter deux commandes, si votre shell est bash ou zsh, vous pouvez utiliser $() pour passer directement le résultat à --strip-components :

tar xvf file.tar --strip-components $(while read; do echo -n "$REPLY" | wc -c; done < <(tar tvf file.tar | egrep -v '^d' | sed 's:[^/]::g') | sort -n | uniq | head -n 1)
x f/
x myfile1
x f/myfile2

Cette commande gère également correctement le cas d'une archive tar sans hiérarchie de répertoires :

touch myfile3
tar cvf file2.tar myfile3
tar xvf file2.tar --strip-components $(while read; do echo -n "$REPLY" | wc -c; done < <(tar tvf file2.tar | egrep -v '^d' | sed 's:[^/]::g') | sort -n | uniq | head -n 1)
x myfile3

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X