Làm cách nào tôi có thể giải nén .tar.gz trong một bước (sử dụng 7-Zip)?


82

Tôi đang sử dụng 7-Zip trên Windows XP và bất cứ khi nào tôi tải xuống tệp .tar.gz, tôi phải thực hiện hai bước để giải nén hoàn toàn (các) tệp.

  1. Tôi nhấp chuột phải vào tệp example.tar.gz và chọn 7-Zip -> Trích xuất ở đây từ menu ngữ cảnh.
  2. Sau đó tôi lấy tệp example.tar kết quả và nhấp chuột phải lần nữa và chọn 7-Zip -> Trích xuất ở đây từ menu ngữ cảnh.

Có cách nào thông qua menu ngữ cảnh để làm điều này trong một bước không?

Câu trả lời:


46

Không hẳn vậy. Tệp .tar.gz hoặc .tgz thực sự có hai định dạng: .tarlà tệp lưu trữ và .gzlà tệp nén. Vì vậy, bước đầu tiên giải nén và bước thứ hai trích xuất kho lưu trữ.

Để làm tất cả trong một bước, bạn cần tarchương trình. Cygwin bao gồm điều này.

tar xzvf foobaz.tar.gz

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

Bạn cũng có thể thực hiện "trong một bước" bằng cách mở tệp trong GUI 7-zip: Mở .tar.gztệp, nhấp đúp vào .tartệp được bao gồm , sau đó trích xuất các tệp đó vào vị trí bạn chọn.

Có một chuỗi hoạt động dài ở đây của những người yêu cầu / bỏ phiếu để xử lý một bước các tệp tgz và bz2. Hành động thiếu cho đến nay cho thấy nó sẽ không xảy ra cho đến khi ai đó bước và đóng góp một cách có ý nghĩa (mã, tiền, một cái gì đó).


70
Nếu 7zip là thông minh, nó sẽ thực hiện theo một bước theo mặc định, vì 99,99% thời gian đó là những gì người dùng muốn làm. Trên thực tế, đây là hoạt động mặc định của WinRar.
davr

6
@davr: 7-zip là một nỗ lực nguồn mở; hãy yêu cầu tính năng này đây là cách v4,65 hoạt động; Tôi đã không thử các bảng chữ cái v9.x mới hơn, vì vậy nó có thể đã được bao gồm.
quack quixote

Yah, đây là những gì tôi nhớ từ hoạt động của WinRar. Tôi có thể xác nhận rằng cho đến ngày hôm nay, tháng 10 năm 2012, 7zip vẫn không tự động giải nén với 1 bước. thở dài
fedmich

8
Lưu ý rằng các hướng dẫn "trong một bước" không thực sự thực hiện trong một bước, nó thực sự giải nén .gz vào một thư mục tạm thời, sau đó mở tệp .tar trong 7-zip. Khi tài liệu lưu trữ đủ nhỏ, hầu như không đáng chú ý, nhưng nó rất đáng chú ý trên kho lưu trữ lớn. Chỉ cần nghĩ rằng xứng đáng làm rõ.
naasking

Có một câu trả lời mới với các hướng dẫn một bước.
Barett

25

Câu hỏi cũ, nhưng tôi đã vật lộn với nó ngày hôm nay vì vậy đây là 2c của tôi. Công cụ dòng lệnh 7zip "7z.exe" (tôi đã cài đặt v9.22) có thể ghi vào thiết bị xuất chuẩn và đọc từ stdin để bạn có thể làm mà không cần tệp tar trung gian bằng cách sử dụng đường ống:

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

Ở đâu:

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

Xem tệp trợ giúp (7-zip.chm) trong thư mục cài đặt để biết thêm thông tin về các lệnh và chuyển đổi dòng lệnh.

Bạn có thể tạo một mục menu ngữ cảnh cho các tệp .tar.gz / .tgz gọi lệnh trên bằng regedit hoặc công cụ của bên thứ 3 như stexbar .


công tắc -aoa làm gì? Nó không được liệt kê trong -? trang
Superole

2
..ahh nhưng nó nằm trong tập tin trợ giúp; -ao [a | s | t | u] (chế độ ghi đè). do đó: -aoa = ghi đè lên tất cả các tệp hiện có nhắc nhở
Superole

Câu trả lời tốt nhưng vòng lặp không được OP yêu cầu. Câu trả lời một dòng của Joachim (tương tự) là tuyệt vời và chính xác!
Jason

@Jason câu trả lời đó hoàn toàn giống với câu trả lời SO stackoverflow.com/a/14699663/737471 Tôi chỉ có thể chỉnh sửa câu này ...
user2856

9

Bắt đầu với 7-zip 9.04, có một tùy chọn dòng lệnh để thực hiện trích xuất kết hợp mà không sử dụng bộ lưu trữ trung gian cho .tartệp đơn giản :

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

-tgziplà cần thiết nếu tập tin đầu vào được đặt tên .tgzthay vì .tar.gz.


2
Có cách nào để đưa nó vào menu ngữ cảnh Windows 10 Explorer không?
Brian Leishman

4

Bạn đang sử dụng Windows XP, do đó bạn nên cài đặt Windows Scripting Host theo mặc định. Như đã nói, đây là tập lệnh WSH JScript để làm những gì bạn cần. Chỉ cần sao chép mã vào tên tệp xtract.bat hoặc một cái gì đó dọc theo các dòng đó (Có thể là bất cứ điều gì miễn là nó có phần mở rộng .bat) và chạy:

xtract.bat example.tar.gz

Theo mặc định, tập lệnh sẽ kiểm tra thư mục của tập lệnh, cũng như PATHbiến môi trường của hệ thống của bạn cho 7z.exe. Nếu bạn muốn thay đổi giao diện của nội dung, bạn có thể thay đổi biến SevenZipExe ở đầu tập lệnh thành bất kỳ tên nào bạn muốn tên thực thi. (Ví dụ: 7za.exe hoặc 7z-real.exe) Bạn cũng có thể đặt thư mục mặc định cho tệp thực thi bằng cách thay đổi SevenZipDir. Vì vậy, nếu 7z.exelà tại C:\Windows\system32\7z.exe, bạn sẽ đặt:

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

Dù sao, đây là kịch bản:

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

Không phải là tôi biết. Ban đầu tôi đã tìm thấy nó trong kho lưu trữ nguồn sau: github.com/ynkdir/winscript Nó hoạt động, bởi vì công cụ jscript WSH dường như bỏ qua bit đầu tiên, cho đến khi bình luận bắt đầu. Thông tin chi tiết có thể được tìm thấy tại: stackoverflow.com/questions/4999395/ Khăn
Charles Grunwald

đã tìm thấy điều này: javascriptkit.com/javatutors/conditablecompile2.shtml dường như chỉ ra đó @set @var = valuelà cú pháp JScript để khai báo các biến thời gian biên dịch. Vì vậy, cả JScript hợp lệ và lệnh CMD
hdgarrood

2

Như bạn có thể thấy 7-Zip không tốt lắm về điều này. Mọi người đã yêu cầu hoạt động nguyên tử tarball từ năm 2009. Đây là một chương trình nhỏ (490 KB) trong Go có thể làm điều đó, tôi đã biên soạn nó cho bạn.

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

Bắt đầu từ Windows 10 build 17063 tarcurlđược hỗ trợ, do đó có thể giải nén tệp .tar.gz trong một bước bằng cách sử dụng tarlệnh, như dưới đây.

tar -xzvf your_archive.tar.gz

Nhập tar --helpđể biết thêm thông tin về tar.


tar, curl, ssh, sftp, rmb dán và màn hình rộng hơn. Người dùng hư hỏng thối.
mckenzm

0

7za hoạt động đúng như dưới đây:

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

3
Bạn có thể thêm một số bối cảnh xung quanh cách lệnh này hoạt động? Xin vui lòng xem Làm thế nào để trả lời và đi tour của chúng tôi .
Burgi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.