Jak rozpakować plik .tar.gz w jednym kroku (używając 7-Zip)?


82

Korzystam z 7-Zip w systemie Windows XP i za każdym razem, gdy pobieram plik .tar.gz, muszę całkowicie wyodrębnić plik (i).

  1. Klikam prawym przyciskiem myszy plik example.tar.gz i wybieram 7-Zip -> Wyodrębnij tutaj z menu kontekstowego.
  2. Następnie biorę wynikowy plik example.tar i ponownie kliknij prawym przyciskiem myszy i wybierz 7-Zip -> Wyodrębnij tutaj z menu kontekstowego.

Czy istnieje sposób w menu kontekstowym, aby zrobić to w jednym kroku?

Odpowiedzi:


46

Nie całkiem. Plik .tar.gz lub .tgz to tak naprawdę dwa formaty: .tararchiwum i .gzkompresja. Tak więc pierwszy krok dekompresuje, a drugi krok wypakowuje archiwum.

Aby zrobić to wszystko w jednym kroku, potrzebujesz tarprogramu. Cygwin obejmuje to.

tar xzvf foobaz.tar.gz

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

Możesz to również zrobić „w jednym kroku”, otwierając plik w 7-zip GUI: Otwórz .tar.gzplik, kliknij dwukrotnie dołączony .tarplik, a następnie wyodrębnij te pliki do wybranej lokalizacji.

Istnieje długa nić tu ludzi prosząc / głosowanie na obsługę jednoetapowy plików TGZ i BZ2. Dotychczasowy brak działania wskazuje, że tak się nie stanie, dopóki ktoś nie podejmie kroków i nie wniesie znaczącego wkładu (kod, pieniądze, coś).


70
Gdyby 7zip był inteligentny, zrobiłby to domyślnie w jednym kroku, ponieważ 99,99% czasu to właśnie chce użytkownik. W rzeczywistości jest to domyślna operacja WinRar.
davr,

6
@davr: 7-zip jest przedsięwzięciem typu open source; poproś o tę funkcję. tak działa wersja 4.65; nie próbowałem nowszej wersji alfy v9.x, więc może już być uwzględniona.
szarlatan

Tak, tego brakuje mi w operacji WinRar. Mogę potwierdzić, że do dzisiaj, październik 2012, 7zip nadal nie dekompresuje się automatycznie za pomocą 1 kroku. westchnienie
fedmich,

8
Zauważ, że instrukcje „w jednym kroku” tak naprawdę nie robią tego w jednym kroku, faktycznie dekompresują .gz do folderu tymczasowego, a następnie otwierają plik .tar w 7-zip. Gdy archiwa są wystarczająco małe, jest to prawie niezauważalne, ale bardzo widoczne w dużych archiwach. Pomyślałem, że zasługuje na wyjaśnienie.
naasking 25.10.13

Istnieje nowa odpowiedź z instrukcjami krok po kroku.
Barett

25

Stare pytanie, ale zmagałem się z tym dzisiaj, więc oto mój 2c. Narzędzie wiersza polecenia 7zip „7z.exe” (mam zainstalowaną wersję 9.22) może zapisywać na standardowe wyjście i czytać ze standardowego wejścia, dzięki czemu można obejść się bez pośredniego pliku tar za pomocą potoku:

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

Gdzie:

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

Zobacz plik pomocy (7-zip.chm) w katalogu instalacyjnym, aby uzyskać więcej informacji na temat poleceń i przełączników wiersza poleceń.

Możesz utworzyć pozycję menu kontekstowego dla plików .tar.gz / .tgz, która wywołuje powyższe polecenie przy użyciu regedit lub narzędzia zewnętrznego, takiego jak Stexbar .


co robi przełącznik -aoa? Nie ma go w -? strona
Superole,

2
..ahh, ale jest w pliku pomocy; -ao [a | s | t | u] (tryb zastępowania). dlatego: -aoa = zastąp wszystkie istniejące pliki bez monitu
Superole

Dobra odpowiedź, ale OP nie poprosił o zapętlenie. (Podobna) odpowiedź Joachima w jednym wierszu jest świetna i do rzeczy!
Jason

@Jason, ta odpowiedź jest dokładnie taka sama jak moja odpowiedź SO stackoverflow.com/a/14699663/737471 Mogę po prostu edytować tę ...
user2856

9

Począwszy od wersji 7-zip 9.04, dostępna jest opcja wiersza polecenia, aby wykonać ekstrakcję łączoną bez użycia pamięci pośredniej dla zwykłego .tarpliku:

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

-tgzipjest potrzebny, jeśli plik wejściowy ma nazwę .tgzzamiast .tar.gz.


2
Jakiś sposób, aby dostać się do menu kontekstowego Eksploratora Windows 10?
Brian Leishman,

4

Korzystasz z systemu Windows XP, więc powinieneś mieć domyślnie zainstalowany Windows Scripting Host. Biorąc to pod uwagę, oto skrypt WSH JScript do robienia tego, czego potrzebujesz. Po prostu skopiuj kod do nazwy pliku xtract.bat lub coś wzdłuż tych linii (może być dowolny, pod warunkiem, że ma rozszerzenie .bat) i uruchom:

xtract.bat example.tar.gz

Domyślnie skrypt sprawdzi folder skryptu, a także PATHzmienną środowiskową systemu pod kątem 7z.exe. Jeśli chcesz zmienić wygląd rzeczy, możesz zmienić zmienną SevenZipExe u góry skryptu na dowolną nazwę pliku wykonywalnego. (Na przykład 7za.exe lub 7z-real.exe) Możesz również ustawić domyślny katalog dla pliku wykonywalnego, zmieniając SevenZipDir. Więc jeśli 7z.exejest C:\Windows\system32\7z.exe, wstawiłbyś:

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

Tak czy inaczej, oto skrypt:

@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);

Nie, że jestem świadomy. Początkowo znalazłem go w następującym repozytorium źródłowym: github.com/ynkdir/winscript Działa, ponieważ silnik WSH jscript najwyraźniej ignoruje pierwszy bit, aż do momentu rozpoczęcia komentarza. Więcej informacji można znaleźć na stronie: stackoverflow.com/questions/4999395/...
Charles Grunwald

znaleziono to: javascriptkit.com/javatutors/conditionalcompile2.shtml, co wydaje się wskazywać, że @set @var = valuejest to składnia JScript do deklarowania zmiennych czasu kompilacji. Więc jest to zarówno poprawny JScript, jak i polecenie CMD
hdgarrood

2

Jak widać 7-Zip nie jest w tym bardzo dobry. Ludzie pytają o operację atomową tarball od 2009 roku. Oto mały program (490 KB) w Go, który może to zrobić, skompilowałem go dla ciebie.

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)
    }
  }
}

1

Począwszy od systemu Windows 10 kompilacja 17063 tari curlsą obsługiwane, dlatego można rozpakować plik .tar.gz w jednym kroku za pomocą tarpolecenia, jak poniżej.

tar -xzvf your_archive.tar.gz

Wpisz tar --helpwięcej informacji na temat tar.


tar, curl, ssh, sftp, rmb wklejanie i szerszy ekran. Użytkownicy są rozpieszczeni.
mckenzm

0

7za działa poprawnie, jak poniżej:

7za.exe x D:\pkg-temp\Prod-Rtx-Service.tgz -so | 7za.exe x -si -ttar -oD:\pkg-temp\Prod-Rtx-Service

3
Czy możesz dodać kontekst dotyczący działania tego polecenia? Zobacz Jak odpowiedzieć i wybrać się na naszą wycieczkę .
Burgi
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.