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


82

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

  1. Faccio clic con il pulsante destro del mouse sul file example.tar.gz e scelgo 7-Zip -> Estrai qui dal menu di scelta rapida.
  2. Prendo quindi il file example.tar risultante e faccio nuovamente clic con il pulsante destro del mouse e scelgo 7-Zip -> Estrai qui dal menu di scelta rapida.

Esiste un modo attraverso il menu di scelta rapida per farlo in un solo passaggio?

Risposte:


46

Non proprio. Un file .tar.gz o .tgz ha due formati: .tarl'archivio e .gzla compressione. Quindi il primo passaggio si decomprime e il secondo passaggio estrae l'archivio.

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

tar xzvf foobaz.tar.gz

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

Puoi anche farlo "in un solo passaggio" aprendo il file nella GUI a 7 zip: apri il .tar.gzfile, fai doppio clic sul .tarfile incluso , quindi estrai quei file nella posizione che preferisci.

C'è una lunga discussione qui di persone che chiedono / votano per la gestione in un solo passaggio dei file tgz e bz2. L'azione di mancanza finora indica che non accadrà finché qualcuno non interverrà e contribuirà in modo significativo (codice, denaro, qualcosa).


70
Se 7zip fosse intelligente, lo farebbe in un unico passaggio per impostazione predefinita, poiché il 99,99% delle volte è ciò che l'utente vuole fare. In realtà, questa è l'operazione predefinita di WinRar.
dav

6
@davr: 7-zip è uno sforzo open source; non esitate a richiedere questa funzione. ecco come funziona v4.65; non ho provato i più recenti alfa v9.x, quindi potrebbe già essere incluso.
Quack Quixote

Sì, questo è ciò che mi manca dall'operazione di WinRar. Potrei confermare che fino ad oggi, ottobre 2016, 7zip non si decomprime automaticamente con 1 passaggio. sigh
fedmich,

8
Si noti che le istruzioni "in un passaggio" non lo fanno effettivamente in un passaggio, in realtà decomprime il .gz in una cartella temporanea, quindi apre il file .tar in 7-zip. Quando gli archivi sono abbastanza piccoli, è quasi impercettibile, ma è molto evidente su archivi di grandi dimensioni. Ho solo pensato che meritasse un chiarimento.
naasking

C'è una nuova risposta con le istruzioni in un solo passaggio.
Barett,

25

Vecchia domanda, ma oggi stavo lottando con questo, quindi ecco il mio 2c. Lo strumento da riga di comando 7zip "7z.exe" (ho installato 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 ulteriori informazioni sui comandi e sulle opzioni della riga di comando.

È possibile creare una voce del menu di scelta rapida per i file .tar.gz / .tgz che chiama il comando sopra usando regedit o uno strumento di terze parti come stexbar .


cosa fa l'interruttore -aoa? Non è elencato in -? pagina
Superole,

2
..ahh ma è nel file di aiuto; -ao [a | s | t | u] (modalità di sovrascrittura). quindi: -aoa = sovrascrive tutti i file esistenti senza prompt
Superole,

Buona risposta ma il loop non è stato richiesto dall'OP. La risposta di una riga (simile) di Joachim è ottima e al punto!
Jason

@Jason quella risposta è esattamente la stessa della mia risposta SO stackoverflow.com/a/14699663/737471 Potrei solo modificare questa ...
user2856

9

A partire da 7-zip 9.04 esiste un'opzione da riga di comando per eseguire l'estrazione combinata senza utilizzare l'archiviazione intermedia per il .tarfile normale :

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

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


2
Qualche modo per farlo nel menu contestuale di Windows 10 Explorer?
Brian Leishman,

4

Stai utilizzando Windows XP, quindi dovresti avere Windows Scripting Host installato per impostazione predefinita. Detto questo, ecco uno script WSH JScript per fare ciò di cui hai bisogno. Basta copiare il codice su un nome file xtract.bat o qualcosa del genere (può essere qualsiasi cosa purché abbia l'estensione .bat) ed eseguire:

xtract.bat example.tar.gz

Per impostazione predefinita, lo script controlla la cartella dello script, nonché la PATHvariabile di ambiente del sistema per 7z.exe. Se vuoi cambiare il modo in cui cerca qualcosa, puoi cambiare la variabile SevenZipExe nella parte superiore dello script in qualunque cosa tu voglia che sia il nome dell'eseguibile. (Ad esempio, 7za.exe o 7z-real.exe) È inoltre possibile impostare una directory predefinita per l'eseguibile modificando SevenZipDir. Quindi se 7z.exeè a C:\Windows\system32\7z.exe, dovresti mettere:

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

Comunque, ecco lo 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);

Non che ne sia consapevole. Inizialmente l'ho trovato nel seguente repository di origine: github.com/ynkdir/winscript Funziona, perché il motore jscript WSH sembra ignorare il primo bit, fino a quando non inizia il commento. Ulteriori informazioni sono disponibili all'indirizzo: stackoverflow.com/questions/4999395/…
Charles Grunwald,

trovato questo: javascriptkit.com/javatutors/conditionalcompile2.shtml che sembra indicare che @set @var = valueè la sintassi JScript per dichiarare le variabili di compilazione. Quindi è sia JScript valido sia un comando CMD
hdgarrood l'

2

Come puoi vedere 7-Zip non è molto bravo in questo. La gente chiede un'operazione atomica tarball dal 2009. Ecco un piccolo programma (490 KB) in Go che può farlo, l'ho 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)
    }
  }
}

1

A partire da Windows 10 build 17063 tare curlsono supportati, quindi è possibile decomprimere un file .tar.gz in un solo passaggio utilizzando il tarcomando, come di seguito.

tar -xzvf your_archive.tar.gz

Digitare tar --helpper ulteriori informazioni su tar.


catrame, ricciolo, ssh, sftp, incollatura rmb e schermo più ampio. Gli utenti sono viziati marci.
mckenzm,

0

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

3
Puoi aggiungere un contesto su come funziona questo comando? Consulta la sezione Come rispondere e partecipa al nostro tour .
Burgi,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.