web-dev-qa-db-fra.com

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

J'utilise 7-Zip sous 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?

78
quickcel

Pas vraiment. Un fichier .tar.gz ou .tgz a deux formats: .tar est l’archive et .gz est la 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 programme tar. 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 de 7-Zip: Ouvrez le fichier .tar.gz, double-cliquez sur le fichier .tar inclus, puis extrayez ces fichiers à l'emplacement de votre choix.

Il y a un long fil de discussion ici de personnes demandant/votant pour le traitement en une étape des fichiers tgz et bz2. Le manque d’action jusqu’à présent indique que cela ne se produira que lorsque quelqu'un interviendra et apportera une contribution significative (code, argent, quelque chose).

44
quack quixote

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

Voir 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 .

21
user2856

À partir de 7-Zip 9.04, une option de ligne de commande permet d'effectuer l'extraction combinée sans utiliser de stockage intermédiaire pour le fichier plain .tar:

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

-tgzip est nécessaire si le fichier d'entrée est nommé .tgz au lieu de .tar.gz.

7
Joachim Sauer

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 porte l'extension .bat) et lancez:

xtract.bat example.tar.gz

Par défaut, le script vérifie le dossier du script, ainsi que la variable d'environnement PATH de votre système pour 7z.exe. Si vous souhaitez modifier l'apparence des éléments, vous pouvez modifier la variable SevenZipExe en haut du script pour définir 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.exe est à C:\Windows\system32\7z.exe, vous devriez mettre:

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);
4
Charles Grunwald

Comme vous pouvez le constater, 7-Zip n’est pas très bon à cet égard. Les gens ont demandé tarball opération atomique depuis 2009. Voici un petit programme (490 KB) dans Go qui peut le faire, je l'ai 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)
    }
  }
}
2
Steven Penny

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
0
Alan Hu