it-swarm-eu.dev

Come posso decomprimere un .tar.gz in un solo passaggio (usando 7-Zip)?

Sto usando 7-Zip su Windows XP e ogni volta che scarico un file .tar.gz mi occorrono due passaggi per estrarre completamente il/i file/i.

  1. Faccio clic con il pulsante destro del mouse su example.tar.gz e scegliere 7-Zip -> Estrai qui dal menu di scelta rapida.
  2. Quindi prendo il risultante example.tar file e di nuovo il tasto destro del mouse e scelgo 7-Zip -> Estrai qui dal menu di scelta rapida.

C'è un modo attraverso il menu di scelta rapida per fare questo in un unico passaggio?

78
quickcel

Non proprio. Un file .tar.gz o .tgz è in realtà in due formati: .tar è l'archivio e .gz è la compressione. Quindi il primo passo decomprime e il secondo passo estrae l'archivio.

Per fare tutto in un solo passaggio, è necessario il programma tar. Cygwin include questo.

tar xzvf foobaz.tar.gz

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

Si potrebbe anche farlo "in un solo passaggio" aprendo il file nella GUI 7-Zip: Aprire il file .tar.gz, fare doppio clic sul file .tar incluso, quindi estrarre quei file nella posizione scelta.

C'è una lunga discussione qui di persone che chiedono/votano per la gestione in un solo passaggio dei file tgz e bz2. La mancanza di azione finora indica che non succederà fino a quando qualcuno non salirà e contribuirà in modo significativo (codice, denaro, qualcosa).

44
quack quixote

Vecchia domanda, ma stavo lottando con esso oggi, quindi ecco il mio 2c. Lo strumento da riga 7zip "7z.exe" (ho installato la v9.22) può scrivere su stdout e leggere da stdin in modo da poter fare a meno del file tar intermedio usando una pipe:

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

Dove:

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

Vedere il file della guida (7-Zip.chm) nella directory di installazione per maggiori informazioni sui comandi e le opzioni della riga di comando.

Puoi creare una voce del menu contestuale per i file .tar.gz/.tgz che chiama il comando precedente usando regedit o uno strumento di terze parti come stexbar .

21
user2856

A partire da 7-Zip 9.04 è disponibile un'opzione della riga di comando per eseguire l'estrazione combinata senza utilizzare la memoria intermedia per il file .tar semplice:

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

-tgzip è necessario se il file di input è denominato .tgz anziché .tar.gz.

7
Joachim Sauer

Stai usando Windows XP, quindi dovresti avere Windows Scripting Host installato per impostazione predefinita. Detto questo, ecco uno script WSH di JScript per fare ciò che ti serve. Basta copiare il codice in un nome file xtract.bat o qualcosa di simile (può essere qualsiasi cosa purché abbia l'estensione .bat), ed eseguire:

xtract.bat example.tar.gz

Per impostazione predefinita, lo script controllerà la cartella dello script, così come la variabile d'ambiente PATH del sistema per 7z.exe. Se si desidera modificare la modalità di ricerca, è possibile modificare la variabile SevenZipExe nella parte superiore dello script in base al nome del file eseguibile. (Ad esempio, 7za.exe o 7z-real.exe) È anche possibile impostare una directory predefinita per l'eseguibile modificando SevenZipDir. Quindi se 7z.exe è a C:\Windows\system32\7z.exe, dovresti inserire:

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

Ad ogni modo, ecco la sceneggiatura:

@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

Come puoi vedere, 7-Zip non è molto bravo in questo. Le persone sono state chiedono tarball atomic operation dal 2009. Ecco un piccolo programma (490 KB) in Go che può farlo, I lo ha compilato per te.

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 funziona correttamente come di seguito:

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