Як можна розпакувати .tar.gz за один крок (за допомогою 7-Zip)?


82

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

  1. Клацніть правою кнопкою миші файл example.tar.gz і виберіть 7-Zip -> Витягнути тут з контекстного меню.
  2. Потім я беру отриманий файл example.tar і клацніть правою кнопкою миші ще раз і вибираю 7-Zip -> Витягнути тут з контекстного меню.

Чи є можливість через контекстне меню зробити це за один крок?

Відповіді:


46

Не зовсім. Файл .tar.gz або .tgz дійсно має два формати: .tarце архів та .gzкомпресія. Отже перший крок розпаковується, а другий крок витягує архів.

Щоб зробити це все в один крок, вам потрібна tarпрограма. Цигвін включає це.

tar xzvf foobaz.tar.gz

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

Ви також можете зробити це "за один крок", відкривши файл у 7-zip GUI: Відкрийте .tar.gzфайл, двічі клацніть включений .tarфайл, а потім витягніть ці файли до обраного вами місця.

Там довгий хід нитка тут людей просять / голосувати за один-ступінчастою обробки TGZ і BZ2 файлів. Наразі відсутність дій вказує на те, що це не відбудеться до тих пір, поки хтось не зробить кроку та зробить значимий внесок (код, гроші, щось).


70
Якби 7zip був розумним, він би зробив це за один крок за замовчуванням, оскільки 99,99% часу саме так хоче користувач. Насправді це операція за замовчуванням WinRar.
davr

6
@davr: 7-zip - це спроба з відкритим кодом; не соромтеся запитати цю функцію. так працює v4.65; я не пробував новіші альфа-версії v9.x, тому він уже може бути включений.
шарлатаний кіхот

Так, це я сумую за операцією WinRar. Я можу підтвердити, що до сьогодні, Oct2012, 7zip досі не автоматично розпаковується з 1 кроком. зітхання
fedmich

8
Зауважте, що інструкції "в один крок" насправді не роблять це за один крок, він фактично декомпресує .gz у тимчасову папку, а потім відкриває .tar файл у 7-zip. Коли архіви досить малі, це навряд чи помітно, але це дуже помітно у великих архівах. Просто подумав, що заслуговує роз'яснення.
naasking

З'явилася нова відповідь з однокроковими вказівками.
Баретт

25

Старе питання, але я сьогодні з цим боровся, тож ось мій 2с. Інструмент командного рядка 7zip "7z.exe" (у мене встановлено v9.22) може записувати в stdout і читати з stdin, щоб ви могли обходитися без проміжного файлу 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 .


що робить перемикач -aoa? Це не вказано в -? сторінка
Superole

2
..аах, але це у файлі довідки; -ao [a | s | t | u] (режим перезапису). таким чином: -aoa = перезаписати всі існуючі файли без підказки
Superole

Хороша відповідь, але цикл ОП не вимагав. Відповідь Йоахіма (подібний) однорядний - це чудово і до речі!
Джейсон

@Jason ця відповідь точно така ж, як моя відповідь SO stackoverflow.com/a/14699663/737471 Я можу просто відредагувати цю ...
user2856

9

Починаючи з 7-zip 9.04, є варіант командного рядка зробити комбінований видобуток без використання проміжного сховища для простого .tarфайлу:

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

-tgzipпотрібен, якщо вхідний файл названий .tgzзамість .tar.gz.


2
Будь-який спосіб потрапити в контекстне меню Windows 10 Explorer?
Брайан Лейшман

4

Ви використовуєте Windows XP, тому у вас повинен бути встановлений Хост сценарію Windows за замовчуванням. З урахуванням цього, ось сценарій 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);

Не те, що мені відомо. Я спочатку знайшов його в наступному сховищі джерел: github.com/ynkdir/winscript Це працює, тому що двигун jscript WSH, очевидно, ігнорує перший біт, аж поки коментар не почнеться. Більше інформації можна знайти на сайті: stackoverflow.com/questions/4999395/…
Чарльз Грюнвальд

виявив це: javascriptkit.com/javatators/conditionalcompile2.shtml, який, схоже, вказує на те, що @set @var = valueце синтаксис JScript для оголошення змінних часу компіляції. Так що це дійсна JScript та команда CMD
hdgarrood

2

Як бачите, 7-Zip в цьому не дуже добре. Люди просять атомної операції з тарболом з 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)
    }
  }
}

1

Починаючи з Windows 10 build 17063, tarі curlвони підтримуються, тому можна розпакувати файл .tar.gz за один крок за допомогою tarкоманди, як показано нижче.

tar -xzvf your_archive.tar.gz

Введіть tar --helpдля отримання додаткової інформації про tar.


tar, curl, ssh, sftp, вставлення rmb та ширший екран. Користувачі розбещені гнилі.
mckenzm

0

7za працює належним чином, як показано нижче:

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

3
Чи можете ви додати деякий контекст, як працює ця команда? Будь ласка, подивіться, як відповісти та здійснити нашу екскурсію .
Бургі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.