it-swarm-ru.tech

Как я могу распаковать .tar.gz за один шаг (используя 7-Zip)?

Я использую 7-Zip в Windows XP и ​​всякий раз, когда я загружаю файл .tar.gz, мне требуется два шага, чтобы полностью извлечь файл (ы).

  1. Я щелкаю правой кнопкой мыши на example.tar.gz file и выбираю 7-Zip -> Extract Here из контекстного меню.
  2. Затем я беру полученный файл example.tar и снова щелкаю правой кнопкой мыши и выбираю 7-Zip -> Извлечь здесь из контекстного меню.

Есть ли способ через контекстное меню сделать это за один шаг?

78
quickcel

На самом деле, нет. Файл .tar.gz или .tgz на самом деле имеет два формата: .tar - это архив, а .gz - это сжатие. Таким образом, первый шаг распаковывается, а второй шаг извлекает архив.

Чтобы сделать все это за один шаг, вам нужна программа tar. Cygwin включает это.

tar xzvf foobaz.tar.gz

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

Вы также можете сделать это «за один шаг», открыв файл в графическом интерфейсе 7-Zip: откройте файл .tar.gz, дважды щелкните включенный файл .tar, а затем извлеките эти файлы в нужное место.

Здесь есть длинная ветка здесь людей, которые просят/голосуют за одностадийную обработку файлов tgz и bz2. Пока действие отсутствия указывает на то, что этого не произойдет, пока кто-то не предпримет шаги и не внесет значительный вклад (код, деньги, что-то).

44
quack quixote

Старый вопрос, но я боролся с этим сегодня, так что вот мой 2с. Средство командной строки 7Zip "7z.exe" (у меня установлена ​​версия 9.22) может писать в стандартный вывод и читать из стандартного ввода, так что вы можете обойтись без промежуточного файла tar, используя канал:

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

Куда:

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

См. Файл справки (7-Zip.chm) в каталоге установки для получения дополнительной информации о командах командной строки и переключателях.

Вы можете создать пункт контекстного меню для файлов .tar.gz/.tgz, который вызывает вышеуказанную команду, используя regedit или сторонний инструмент, такой как stexbar .

21
user2856

Начиная с 7-Zip 9.04, имеется опция командной строки, позволяющая выполнять комбинированное извлечение без использования промежуточного хранилища для простого файла .tar:

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

-tgzip необходим, если входной файл называется .tgz вместо .tar.gz.

7
Joachim Sauer

Вы используете Windows XP, поэтому у вас должен быть установлен Windows Scripting Host по умолчанию. С учетом вышесказанного, вот сценарий WSH JScript, чтобы сделать то, что вам нужно. Просто скопируйте код в имя файла xtract.bat или что-то в этом духе (может быть любым, если оно имеет расширение .bat) и выполните

xtract.bat example.tar.gz

По умолчанию сценарий проверяет папку сценария, а также переменную среды PATH в вашей системе для 7z.exe. Если вы хотите изменить то, как он выглядит, вы можете изменить переменную SevenZipExe в верхней части скрипта на любое имя исполняемого файла. (Например, 7za.exe или 7z-real.exe) Вы также можете установить каталог по умолчанию для исполняемого файла, изменив SevenZipDir. Так что, если 7z.exe находится в C:\Windows\system32\7z.exe, вы бы поставили:

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

В любом случае, вот сценарий:

@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

Как видите, 7-Zip не очень хорош в этом. Люди просят tarball atomic operation с 2009 года. Вот небольшая программа (490 КБ) на Go, которая может это сделать, я скомпилировал ее для вас.

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 работает правильно, как показано ниже:

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