Wie kann ich eine .tar.gz in einem Schritt entpacken (mit 7-Zip)?

82

Ich verwende 7-Zip unter Windows XP und beim Herunterladen einer .tar.gz-Datei benötige ich zwei Schritte, um die Datei (en) vollständig zu extrahieren.

  1. Ich klicke mit der rechten Maustaste auf die Datei example.tar.gz und wähle aus dem Kontextmenü 7-Zip -> Hier extrahieren.
  2. Ich nehme dann die resultierende example.tar- Datei und klicke erneut mit der rechten Maustaste und wähle 7-Zip -> Hier extrahieren aus dem Kontextmenü.

Gibt es einen Weg durch das Kontextmenü, um dies in einem Schritt zu tun?

quickcel
quelle

Antworten:

46

Nicht wirklich. Eine .tar.gz- oder .tgz-Datei besteht eigentlich aus zwei Formaten: .tardem Archiv und .gzder Komprimierung. Der erste Schritt dekomprimiert und der zweite Schritt extrahiert das Archiv.

Um alles in einem Schritt zu erledigen, benötigen Sie das tarProgramm. Cygwin beinhaltet dies.

tar xzvf foobaz.tar.gz

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

Sie können dies auch "in einem Schritt" tun, indem Sie die Datei in der 7-Zip-GUI öffnen: Öffnen Sie die .tar.gzDatei, doppelklicken Sie auf die enthaltene .tarDatei und extrahieren Sie diese Dateien an den Speicherort Ihrer Wahl.

Es gibt einen langen Thread , in dem Leute nach einem einstufigen Umgang mit tgz- und bz2-Dateien fragen / abstimmen. Das bisherige Fehlen von Maßnahmen deutet darauf hin, dass dies erst dann geschehen wird, wenn jemand Schritte unternimmt und einen sinnvollen Beitrag leistet (Code, Geld, etwas).

Quacksalber
quelle
70
Wenn 7zip intelligent wäre, würde es standardmäßig in einem Schritt ausgeführt, da der Benutzer dies in 99,99% der Fälle tun möchte. Tatsächlich ist dies die Standardoperation von WinRar.
Davr
6
@davr: 7-zip ist ein Open-Source-Projekt. Fordern Sie diese Funktion an. So funktioniert v4.65; Ich habe die neueren v9.x-Alphas nicht ausprobiert, daher ist sie möglicherweise bereits enthalten.
Quacksalber 7.
Ja, das vermisse ich von WinRars Betrieb. Ich konnte bestätigen, dass bis heute, Oktober 2012, 7zip immer noch nicht automatisch mit 1 Schritt dekomprimiert wird. Seufzer
fedmich
8
Beachten Sie, dass die Anweisungen "in einem Schritt" dies nicht in einem Schritt ausführen, sondern die .gz-Datei in einen temporären Ordner dekomprimieren und dann die .tar-Datei in 7-zip öffnen. Wenn die Archive klein genug sind, fällt dies kaum auf, bei großen Archiven jedoch sehr stark. Ich dachte nur, das hätte eine Klärung verdient.
Naasking
Es gibt eine neue Antwort mit den Ein-Schritt-Anweisungen.
Barett
25

Alte Frage, aber ich hatte heute Probleme damit, also hier ist meine 2c. Das 7zip-Kommandozeilen-Tool "7z.exe" (ich habe v9.22 installiert) kann in stdout schreiben und von stdin lesen, so dass Sie mit einer Pipe auf die dazwischenliegende tar-Datei verzichten können:

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

Wo:

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

Weitere Informationen zu den Befehlszeilenbefehlen und Schaltern finden Sie in der Hilfedatei (7-zip.chm) im Installationsverzeichnis.

Sie können einen Kontextmenüeintrag für .tar.gz / .tgz-Dateien erstellen, der den obigen Befehl mit regedit oder einem Drittanbieter-Tool wie stexbar aufruft .

user2856
quelle
Was macht der -aoa-Schalter? Es ist nicht aufgeführt in -? Seite
Superole
2
..ahh aber es ist in der Hilfedatei; -ao [a | s | t | u] (Überschreibmodus). also: -aoa = überschreibe alle vorhandenen Dateien ohne Eingabeaufforderung
Superole
Gute Antwort, aber die Schleife wurde vom OP nicht angefordert. Joachim's (ähnliche) einzeilige Antwort ist großartig und auf den Punkt!
Jason
@ Jason diese Antwort ist genau das gleiche wie meine SO Antwort stackoverflow.com/a/14699663/737471 Ich kann nur dieses bearbeiten ...
user2856
9

Ab 7-zip 9.04 gibt es eine Befehlszeilenoption, mit der die kombinierte Extraktion durchgeführt werden kann, ohne dass ein Zwischenspeicher für die einfache .tarDatei verwendet wird:

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

-tgzipwird benötigt, wenn die Eingabedatei .tgzanstelle von benannt wird .tar.gz.

Joachim Sauer
quelle
2
Wie kann man das in das Windows 10 Explorer-Kontextmenü bekommen?
Brian Leishman
4

Sie verwenden Windows XP, daher sollte Windows Scripting Host standardmäßig installiert sein. Nachdem dies gesagt wurde, finden Sie hier ein WSH-JScript-Skript, mit dem Sie das tun können, was Sie benötigen. Kopieren Sie einfach den Code in eine Datei mit dem Namen xtract.bat oder so ähnlich (kann beliebig lang sein, solange sie die Erweiterung hat .bat) und führen Sie Folgendes aus:

xtract.bat example.tar.gz

Standardmäßig überprüft das Skript den Ordner des Skripts sowie die PATHUmgebungsvariable Ihres Systems auf 7z.exe. Wenn Sie ändern möchten, wie es aussieht, können Sie die Variable SevenZipExe oben im Skript in den Namen der ausführbaren Datei ändern. (Zum Beispiel 7za.exe oder 7z-real.exe) Sie können auch ein Standardverzeichnis für die ausführbare Datei festlegen, indem Sie SevenZipDir ändern. Also, wenn 7z.exeist bei C:\Windows\system32\7z.exe, würden Sie sagen:

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

Wie auch immer, hier ist das Drehbuch:

@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
quelle
Nicht dass ich wüsste. Ich fand es anfangs im folgenden Quellrepository: github.com/ynkdir/winscript Es funktioniert, weil die WSH-JScript-Engine anscheinend das erste Bit ignoriert, bis der Kommentar beginnt. Weitere Informationen finden Sie unter: stackoverflow.com/questions/4999395/…
Charles Grunwald
Gefunden: javascriptkit.com/javatutors/conditionalcompile2.shtml. Dies scheint darauf hinzudeuten, dass dies @set @var = valueeine JScript-Syntax zum Deklarieren von Variablen zur Kompilierungszeit ist. Es ist also sowohl ein gültiges JScript als auch ein CMD-Befehl
hdgarrood 11.06.13
2

Wie Sie sehen können, ist 7-Zip nicht sehr gut darin. Die Menschen haben für die Nachfrage Tarball Atom Betrieb seit 2009. Hier ist ein kleines Programm (490 KB) in Go , die es tun, ich kann es kompiliert für Sie.

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
quelle
1

Ab Windows 10 Build 17063 tarund curlunterstützt, ist es daher möglich, eine .tar.gz-Datei mit dem folgenden tarBefehl in einem Schritt zu entpacken .

tar -xzvf your_archive.tar.gz

Geben Sie ein, tar --helpum weitere Informationen zu erhalten tar.

Juniver Hazoic
quelle
tar, curl, ssh, sftp, rmb einfügen und breiterer bildschirm. Benutzer werden faul verwöhnt.
McKenzm
0

7za funktioniert wie folgt:

7za.exe x D:\pkg-temp\Prod-Rtx-Service.tgz -so | 7za.exe x -si -ttar -oD:\pkg-temp\Prod-Rtx-Service
Alan Hu
quelle
3
Können Sie einen Kontext hinzufügen, wie dieser Befehl funktioniert? Bitte lesen Sie Wie Sie antworten und nehmen Sie an unserer Tour teil .
Burgi