Comment décompresser un fichier .tar.gz en une seule étape (avec 7-Zip)?

82

J'utilise 7-Zip sur Windows XP et chaque fois que je télécharge un fichier .tar.gz, il me faut deux étapes pour extraire complètement le (s) fichier (s).

  1. Je clique avec le bouton droit sur le fichier example.tar.gz et choisissez 7-Zip -> Extraire ici dans le menu contextuel.
  2. Je prends ensuite le fichier example.tar obtenu , puis cliquez à nouveau avec le bouton droit de la souris et choisissez 7-Zip -> Extraire ici dans le menu contextuel.

Existe-t-il un moyen via le menu contextuel de le faire en une seule étape?

quickcel
la source

Réponses:

46

Pas vraiment. Un fichier .tar.gz ou .tgz a deux formats: .tarl’archive et .gzla compression. Ainsi, la première étape se décompresse et la deuxième extrait l'archive.

Pour tout faire en une seule étape, vous avez besoin du tarprogramme. Cygwin inclut ceci.

tar xzvf foobaz.tar.gz

; x = eXtract 
; z = filter through gZip
; v = be Verbose (show activity)
; f = filename

Vous pouvez également le faire "en une étape" en ouvrant le fichier dans l'interface graphique à 7 zip: Ouvrez le .tar.gzfichier, double-cliquez sur le .tarfichier inclus , puis extrayez ces fichiers à l'emplacement de votre choix.

Il y a un long fil conducteur ici des personnes demandant / voter pour le traitement d' une étape de fichiers tgz et bzip2. Le manque d’action jusqu’à présent indique que cela ne se produira pas tant que personne n’aura pris la mesure de contribuer de façon significative (code, argent, quelque chose).

Quack Quack
la source
70
Si 7zip était intelligent, il le ferait en une étape par défaut, puisque 99,99% du temps, c'est ce que l'utilisateur veut faire. En fait, c'est l'opération par défaut de WinRar.
davr
6
@davr: 7-zip est un effort open source. n'hésitez pas à demander cette fonctionnalité. Voici comment fonctionne la v4.65. Je n'ai pas essayé les nouveaux alphas v9.x, il est donc peut-être déjà inclus.
Quack Quichotte
Yah, voici ce qui me manque du fonctionnement de WinRar. Je pourrais confirmer qu’aujourd’hui, en octobre 2012, 7zip ne décompresse toujours pas automatiquement en une étape. soupir
fedmich
8
Notez que les instructions "en une étape" ne le font pas en une seule étape. Elles décompressent le fichier .gz dans un dossier temporaire, puis ouvrent le fichier .tar en 7-zip. Quand les archives sont assez petites, c'est à peine perceptible, mais c'est très visible sur les grandes archives. Je pensais que cela méritait une clarification.
Naasking
Il y a une nouvelle réponse avec les instructions en une étape.
Barett
25

Vieille question, mais je me débattais avec elle aujourd'hui alors voici mon 2c. L'outil de ligne de commande 7zip "7z.exe" (j'ai installé la version 9.2.2) peut écrire sur stdout et lire à partir de stdin afin que vous puissiez vous passer du fichier tar intermédiaire en utilisant un tube:

7z x "somename.tar.gz" -so | 7z x -aoa -si -ttar -o"somename"

Où:

x     = Extract with full paths command
-so   = write to stdout switch
-si   = read from stdin switch
-aoa  = Overwrite all existing files without prompt.
-ttar = Treat the stdin byte stream as a TAR file
-o    = output directory

Consultez le fichier d'aide (7-zip.chm) dans le répertoire d'installation pour plus d'informations sur les commandes et les commutateurs en ligne de commande.

Vous pouvez créer une entrée de menu contextuel pour les fichiers .tar.gz / .tgz qui appelle la commande ci-dessus à l'aide de regedit ou d'un outil tiers, tel que stexbar .

utilisateur2856
la source
que fait le commutateur -aoa? Ce n'est pas répertorié dans -? page
Superole
2
..ahh mais c'est dans le fichier d'aide; -ao [a | s | t | u] (mode écrasement). ainsi: -aoa = écrasera tous les fichiers existants sans invite
Superole
Bonne réponse mais la boucle n'a pas été demandée par OP. La réponse d'une seule ligne de Joachim (similaire) est excellente et pertinente!
Jason
Cette réponse est @ Jason exactement la même chose que mon SO répondre stackoverflow.com/a/14699663/737471 je suffit d' éditer celui - ci ...
user2856
9

À partir de 7-zip 9.04, il existe une option de ligne de commande permettant d'effectuer l'extraction combinée sans utiliser de stockage intermédiaire pour le .tarfichier brut :

7z x -tgzip -so theinputfile.tgz | 7z x -si -ttar

-tgzipest nécessaire si le fichier d'entrée est nommé à la .tgzplace de .tar.gz.

Joachim Sauer
la source
2
Y a-t-il moyen d’obtenir cela dans le menu contextuel de Windows 10 Explorer?
Brian Leishman
4

Vous utilisez Windows XP, Windows Scripting Host devrait donc être installé par défaut. Cela dit, voici un script WSH JScript pour faire ce dont vous avez besoin. Copiez simplement le code dans un nom de fichier xtract.bat ou quelque chose du genre (peut être ce que vous voulez tant qu'il a l'extension .bat), et lancez:

xtract.bat example.tar.gz

Par défaut, le script vérifie le dossier du script, ainsi que la PATHvariable d'environnement de votre système pour 7z.exe. Si vous souhaitez modifier l'apparence des éléments, vous pouvez remplacer la variable SevenZipExe en haut du script par le nom de l'exécutable. (Par exemple, 7za.exe ou 7z-real.exe) Vous pouvez également définir un répertoire par défaut pour l'exécutable en modifiant SevenZipDir. Donc si 7z.exeest à C:\Windows\system32\7z.exe, vous mettriez:

var SevenZipDir = "C:\\Windows\\system32";

Quoi qu'il en soit, voici le script:

@set @junk=1 /* vim:set ft=javascript:
@echo off
cscript //nologo //e:jscript "%~dpn0.bat" %*
goto :eof
*/
/* Settings */
var SevenZipDir = undefined;
var SevenZipExe = "7z.exe";
var ArchiveExts = ["zip", "tar", "gz", "bzip", "bz", "tgz", "z", "7z", "bz2", "rar"]

/* Multi-use instances */
var WSH = new ActiveXObject("WScript.Shell");
var FSO = new ActiveXObject("Scripting.FileSystemObject");
var __file__ = WScript.ScriptFullName;
var __dir__ = FSO.GetParentFolderName(__file__);
var PWD = WSH.CurrentDirectory;

/* Prototypes */
(function(obj) {
    obj.has = function object_has(key) {
        return defined(this[key]);
    };
    return obj;
})(this.Object.prototype);

(function(str) {
    str.trim = function str_trim() {
        return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
    };
})(this.String.prototype);

(function(arr) {
    arr.contains = function arr_contains(needle) {
        for (var i in this) {
            if (this[i] == needle) {
                return true;
            }
        }
        return false;
    }
})(this.Array.prototype);

/* Utility functions */
function defined(obj)
{
    return typeof(obj) != "undefined";
}

function emptyStr(obj)
{
    return !(defined(obj) && String(obj).length);
}

/* WSH-specific Utility Functions */
function echo()
{
    if(!arguments.length) return;
    var msg = "";
    for (var n = 0; n < arguments.length; n++) {
        msg += arguments[n];
        msg += " ";
    }
    if(!emptyStr(msg))
        WScript.Echo(msg);
}

function fatal(msg)
{
    echo("Fatal Error:", msg);
    WScript.Quit(1);
}

function findExecutable()
{
    // This function searches the directories in;
    // the PATH array for the specified file name;
    var dirTest = emptyStr(SevenZipDir) ? __dir__ : SevenZipDir;
    var exec = SevenZipExe;
    var strTestPath = FSO.BuildPath(dirTest, exec);
    if (FSO.FileExists(strTestPath))
        return FSO.GetAbsolutePathName(strTestPath);

    var arrPath = String(
            dirTest + ";" + 
            WSH.ExpandEnvironmentStrings("%PATH%")
        ).split(";");

    for(var i in arrPath) {
        // Skip empty directory values, caused by the PATH;
        // variable being terminated with a semicolon;
        if (arrPath[i] == "")
            continue;

        // Build a fully qualified path of the file to test for;
        strTestPath = FSO.BuildPath(arrPath[i], exec);

        // Check if (that file exists;
        if (FSO.FileExists(strTestPath))
            return FSO.GetAbsolutePathName(strTestPath);
    }
    return "";
}

function readall(oExec)
{
    if (!oExec.StdOut.AtEndOfStream)
      return oExec.StdOut.ReadAll();

    if (!oExec.StdErr.AtEndOfStream)
      return oExec.StdErr.ReadAll();

    return -1;
}

function xtract(exec, archive)
{
    var splitExt = /^(.+)\.(\w+)$/;
    var strTmp = FSO.GetFileName(archive);
    WSH.CurrentDirectory = FSO.GetParentFolderName(archive);
    while(true) {
        var pathParts = splitExt.exec(strTmp);
        if(!pathParts) {
            echo("No extension detected for", strTmp + ".", "Skipping..");
            break;
        }

        var ext = pathParts[2].toLowerCase();
        if(!ArchiveExts.contains(ext)) {
            echo("Extension", ext, "not recognized. Skipping.");
            break;
        }

        echo("Extracting", strTmp + "..");
        var oExec = WSH.Exec('"' + exec + '" x -bd "' + strTmp + '"');
        var allInput = "";
        var tryCount = 0;

        while (true)
        {
            var input = readall(oExec);
            if (-1 == input) {
                if (tryCount++ > 10 && oExec.Status == 1)
                    break;
                WScript.Sleep(100);
             } else {
                  allInput += input;
                  tryCount = 0;
            }
        }

        if(oExec. ExitCode!= 0) {
            echo("Non-zero return code detected.");
            break;
        }

        WScript.Echo(allInput);

        strTmp = pathParts[1];
        if(!FSO.FileExists(strTmp))
            break;
    }
    WSH.CurrentDirectory = PWD;
}

function printUsage()
{
    echo("Usage:\r\n", __file__, "archive1 [archive2] ...");
    WScript.Quit(0);
}

function main(args)
{
    var exe = findExecutable();
    if(emptyStr(exe))
        fatal("Could not find 7zip executable.");

    if(!args.length || args(0) == "-h" || args(0) == "--help" || args(0) == "/?")
        printUsage();

    for (var i = 0; i < args.length; i++) {
        var archive = FSO.GetAbsolutePathName(args(i));
        if(!FSO.FileExists(archive)) {
            echo("File", archive, "does not exist. Skipping..");
            continue;
        }
        xtract(exe, archive);
    }
    echo("\r\nDone.");
}

main(WScript.Arguments.Unnamed);
Charles Grunwald
la source
Pas que je sache. Je l'ai initialement trouvé dans le référentiel source suivant: github.com/ynkdir/winscript Cela fonctionne, car le moteur jscript de WSH semble ignorer le premier bit, jusqu'au début du commentaire. Plus d'informations peuvent être trouvées à: stackoverflow.com/questions/4999395/…
Charles Grunwald
a trouvé ceci: javascriptkit.com/javatutors/conditionalcompile2.shtml qui semble indiquer qu'il @set @var = values'agit d'une syntaxe JScript pour la déclaration de variables au moment de la compilation. Donc, il est à la fois valide JScript et une commande CMD
hdgarrood
2

Comme vous pouvez le constater, 7-Zip n’est pas très bon à cet égard. Les gens ont été demandent opération atomique tarball depuis 2009. Voici un petit programme (490 KB) en Go qui peut le faire, je compilé pour vous.

package main
import (
  "archive/tar"
  "compress/gzip"
  "flag"
  "fmt"
  "io"
  "os"
  "strings"
 )

func main() {
  flag.Parse() // get the arguments from command line
  sourcefile := flag.Arg(0)
  if sourcefile == "" {
    fmt.Println("Usage : go-untar sourcefile.tar.gz")
    os.Exit(1)
  }
  file, err := os.Open(sourcefile)
  if err != nil {
    fmt.Println(err)
    os.Exit(1)
  }
  defer file.Close()
  var fileReader io.ReadCloser = file
  // just in case we are reading a tar.gz file,
  // add a filter to handle gzipped file
  if strings.HasSuffix(sourcefile, ".gz") {
    if fileReader, err = gzip.NewReader(file); err != nil {
      fmt.Println(err)
      os.Exit(1)
    }
    defer fileReader.Close()
  }
  tarBallReader := tar.NewReader(fileReader)
  // Extracting tarred files
  for {
    header, err := tarBallReader.Next()
    if err != nil {
      if err == io.EOF {
        break
      }
      fmt.Println(err)
      os.Exit(1)
    }
    // get the individual filename and extract to the current directory
    filename := header.Name
    switch header.Typeflag {
    case tar.TypeDir:
      // handle directory
      fmt.Println("Creating directory :", filename)
      // or use 0755 if you prefer
      err = os.MkdirAll(filename, os.FileMode(header.Mode))
      if err != nil {
        fmt.Println(err)
        os.Exit(1)
      }
    case tar.TypeReg:
      // handle normal file
      fmt.Println("Untarring :", filename)
      writer, err := os.Create(filename)
      if err != nil {
        fmt.Println(err)
        os.Exit(1)
      }
      io.Copy(writer, tarBallReader)
      err = os.Chmod(filename, os.FileMode(header.Mode))
      if err != nil {
        fmt.Println(err)
        os.Exit(1)
      }
      writer.Close()
    default:
      fmt.Printf("Unable to untar type : %c in file %s", header.Typeflag,
      filename)
    }
  }
}
Steven Penny
la source
1

À partir de Windows 10 build 17063, taret curlsont pris en charge, il est donc possible de décompresser un fichier .tar.gz en une étape à l'aide de la tarcommande, comme indiqué ci-dessous.

tar -xzvf your_archive.tar.gz

Tapez tar --helppour plus d'informations sur tar.

Juniver Hazoic
la source
tar, curl, ssh, sftp, rmb coller et écran plus large. Les utilisateurs sont gâtés pourris.
McKenzm
0

7za fonctionne correctement comme ci-dessous:

7za.exe x D:\pkg-temp\Prod-Rtx-Service.tgz -so | 7za.exe x -si -ttar -oD:\pkg-temp\Prod-Rtx-Service
Alan Hu
la source
3
Pouvez-vous ajouter un contexte sur le fonctionnement de cette commande? S'il vous plaît voir comment répondre et prendre notre tour .
Burgi