extrait tar dans le répertoire avec le même nom de base?

18

J'ai un fichier zip comme myArchive123.tar.gz. À l'intérieur, il contient un dossier commehelloWorld

Si je l'extrait: tar -xf myArchive123.tar.gzj'obtiens le helloWorlddossier:

ls 
myArchive123.tar.gz
helloWorld 

Je voudrais que la sortie soit du même nom que le nom de fichier moins l'extension .tar.gz. C'est à dire:

tar <magic paramaters> myArchive123.tar.gz 
ls 
 myArchive123.tar.gz
 myArchive123
cd myArchive123
ls 
  helloWorld

Cela peut-il être fait?

  • Je ne sais jamais ce qu'il y a dans l'archive. Il pourrait s'agir d'un dossier, de nombreux fichiers.
  • Je serais d'accord avec l'utilisation d'un autre outil si tar ne peut pas le faire.
  • Je serais d'accord avec un formulaire plus long qui peut être transformé en script

EDIT
Pendant ce temps, je me suis piraté un script qui semble faire le travail. (voir ma réponse postée ci-dessous). Si cela peut être amélioré, n'hésitez pas à poster des commentaires / réponses supplémentaires. L'essentiel est qu'il devrait être emballable dans une seule ligne comme:

extract <file>
Leo Ufimtsev
la source
1
L'archive contient-elle toujours exactement un dossier?
Mark Plotnick
Je ne sais pas ce qu'il y a dedans au moment de l'extraction. Cela ne devrait pas dépendre non plus de ce qu'il y a dans l'archive. S'il s'agit d'un dossier, extrayez-le dedans. s'il s'agit d'un fichier, extrayez tous les fichiers.
Leo Ufimtsev
En attendant, j'ai reconstitué un script (voir ci-dessous). Je ne peux accepter la réponse que dans 2 jours.
Leo Ufimtsev
L'archive contiendra-t-elle jamais plus d'un dossier au niveau supérieur?
Mark Plotnick

Réponses:

10

Avec gnu tar, vous pouvez utiliser --xform(ou --transform) pour ajouter /prefix/à chaque nom de fichier:

tar -xf myArchive.tar.gz --xform='s|^|myArchive/|S'

Note il n'y a pas de leader /dans prefix/et les sedextrémités d'expression avec Spour exclure les cibles de liens symboliques de transformations de nom de fichier.
Pour le tester (essai à sec):

tar -tf myArchive.tar.gz --xform='s|^|myArchive/|S' --verbose --show-transformed-names

Pour commencer, voici un script très simpliste que vous pourriez invoquer comme extract <file>:

STRIP = $ {1%. *} #Strip dernier suffixe
NAME = $ {STRIP% .tar} #strip .tar suffixe, s'il est présent
tar -xf "$ 1" --xform = "s | ^ | $ NAME / | S" #run, commande
don_crissti
la source
Ceci est proche de ce que je veux, à l'exception que je voudrais pouvoir le regrouper en quelque chose comme: extraire <fichier>
Leo Ufimtsev
Ceci est buggé, il s'arrête au premier point. Par exemple, j'ai un fichier comme celui-ci: eclipse-SDK-4.5M6-linux-gtk-x86_64.tar.gz J'attends une sortie sans le .tar.gz, mais j'obtiens eclipse-sdk-4
Leo Ufimtsev
Dans le script ci-dessus, je supprime l'extension et la supprime davantage si je trouve un «tar».
Leo Ufimtsev
En général, avec de nombreux types d'archives. J'espérais une ligne rapide rapide, je pensais que je manquais peut-être un indicateur d'argument. Mais il semble qu'il n'y ait pas de solution triviale à cela?
Leo Ufimtsev
Bon produit. Cela fonctionne et est plus court que le script que j'ai écrit. Agréable!
Leo Ufimtsev
7

Eh bien, vous pouvez le faire en quelques étapes au moins. Si tu l'as fait

mkdir <archive name>
tar -xf <archive name>.tar.gz --strip-components=1 -C <archive name>

cela permettrait d'accomplir la tâche, même s'il existe peut-être une réponse plus compacte.

Eric Renouf
la source
3

Éditer

La réponse acceptée est plus courte que celle ci-dessous. (faites la même chose, mais plus court est généralement mieux).


J'ai finalement piraté un script pour la tâche à accomplir. il fonctionne avec .tar .tar.gz et .gz

#!/bin/sh
#usage:
# nameOfScript myArchive.tar.gz
# nameOfScript myArchive.gz
# nameOfScript myArchive.tar
#
# Result:
# myArchive   //folder
fileName="${1%.*}" #extracted filename

#handle the case of archive.tar.gz
trailingExtension="${fileName##*.}"
if [ "$trailingExtension" == "tar" ]  
then
    fileName="${fileName%.*}"  #remove trailing  tar.
fi

mkdir "$fileName"
tar -xf "$1" --strip-components=0 -C "$fileName"

Usage:

   nameOfScript archive.tar.gz 
   ls 
    archive
   cd archive 
   ls 
    <archive content>

Remarque, cette solution est capable de points dans un nom de fichier. Par exemple Eclipse-4.5M-SDK.tar.gz.

Je garde le script dans mon dépôt git. Pour la dernière version, voir: https://github.com/LeoUfimtsev/ldts/blob/master/pathscripts/leo-tar-here

Leo Ufimtsev
la source
2

Une autre solution possible consiste à utiliser l' --transformoption:

tar -xzf ARCHIVE_NAME.tgz --transform="s/OLD_DIR_NAME/ARCHIVE_NAME/"

Avec vos fichiers:

tar -xzf myArchive123.tar.gz --transform="s/helloWorld/myArchive123/"
svq
la source
1
mais cela présuppose que vous savez ce qu'il y a à l'intérieur des archives
Leo Ufimtsev
par exemple, comment pourrais-je transformer cela en un script d'une ligne sans savoir ce qu'il y a dans l'archive?
Leo Ufimtsev
Vous avez raison. Ce n'est qu'une solution possible comme je l'ai écrit ici ...
svq
y a-t-il une différence entre cela et --strip-compoments = 0 myArchive123?
Leo Ufimtsev
1
Et --strip-components=0supprime simplement le premier nom de répertoire du chemin et avec l' -Coption stocke les fichiers désarchivés dans le nouveau répertoire.
svq