Có cách nào để chuyển đổi một zip thành tar mà không giải nén nó vào hệ thống tập tin không?


17

Có cách nào để chuyển đổi một zipkho lưu trữ thành một tarkho lưu trữ mà không cần giải nén vào một thư mục tạm thời trước không? (và không có văn bản thực hiện riêng của tôi về tarhoặc unzip)


Bạn có đếm việc gắn kho lưu trữ zip khi giải nén nó vào hệ thống tập tin không? Nếu có, thì bạn có thể làm điều đó mà không cần trích xuất bất cứ điều gì với libarchive nhưng điều đó liên quan đến mã hóa.
Celada

Tôi nghĩ rằng op tìm kiếm một cái gì đó giống như superuser.com/questions/325504/ Đây có phải là điều bạn đang hy vọng đạt được?
vfbsilva

Câu trả lời:


12

Điều này hiện có sẵn dưới dạng lệnh có thể cài đặt từ PyPI, xem phần cuối của bài viết này.


Tôi không biết bất kỳ tiện ích "tiêu chuẩn" nào làm như vậy, nhưng khi tôi cần chức năng này, tôi đã viết đoạn mã Python sau để chuyển từ kho lưu trữ tar nén ZIP sang Bzip2 mà không trích xuất bất cứ thứ gì vào đĩa trước:

#! /usr/bin/env python

"""zip2tar """

import sys
import os
from zipfile import ZipFile
import tarfile
import time

def main(ifn, ofn):
    with ZipFile(ifn) as zipf:
        with tarfile.open(ofn, 'w:bz2') as tarf:
            for zip_info in zipf.infolist():
                #print zip_info.filename, zip_info.file_size
                tar_info = tarfile.TarInfo(name=zip_info.filename)
                tar_info.size = zip_info.file_size
                tar_info.mtime = time.mktime(list(zip_info.date_time) +
                                         [-1, -1, -1])
                tarf.addfile(
                    tarinfo=tar_info,
                    fileobj=zipf.open(zip_info.filename)
                )

input_file_name = sys.argv[1]
output_file_name = os.path.splitext(input_file_name)[0] + '.tar.bz2'

main(input_file_name, output_file_name)

Chỉ cần lưu nó vào zip2tarvà làm cho nó thực thi hoặc lưu nó vào zip2tar.pyvà chạy python zip2tar.py. Cung cấp tên tệp ZIP làm đối số cho tập lệnh, tên tệp đầu ra xyz.zipsẽ là xyz.tar.bz2.

Đầu ra được nén Bzip2 thường nhỏ hơn nhiều so với tệp zip vì tệp sau không sử dụng các mẫu nén trên nhiều tệp, nhưng cũng có ít khả năng khôi phục tệp sau nếu có gì đó trong tệp Bzip2 bị sai.

Nếu bạn không muốn đầu ra được nén, hãy xóa :bz2.bz2khỏi mã.


Nếu bạn đã pipcài đặt trong môi trường python3, bạn có thể làm:

pip3 install ruamel.zip2tar

để có được một zip2tartiện ích dòng lệnh làm như trên (từ chối trách nhiệm: Tôi là tác giả của gói đó).


1
Đẹp một. Có vẻ như tập lệnh không thực hiện bất kỳ nỗ lực nào để sao chép siêu dữ liệu như thời gian sửa đổi tệp và quyền trên toàn bộ định dạng lưu trữ thay đổi, nhưng tôi nghĩ bạn có thể thêm nó khá dễ dàng.
Celada

@Celada Tôi đã thêm thời gian sửa đổi tệp (đã bỏ lỡ trong khi sao chép và dán từ mã gốc của mình), tôi không chắc liệu tiêu chuẩn ZIP có thực sự có quyền hay không, AFAIK (hiện đại) hoàn thiện hơn đối với ZIP theo định hướng của Windows .
Anthon

Chính xác những gì tôi đang tìm kiếm. Tôi mong đợi một tiện ích như thế này sẽ có sẵn từ các gói unix tiêu chuẩn. Giấy phép này là gì? Tôi muốn đề xuất nó được bao gồm trong một số gói (ví dụ, các bản dịch của Debian), có lẽ sau một số khái quát.
rbrito

Một nhận xét khác: tài liệu tham khảo timethiếu import.
rbrito

@rbrito Tôi sẽ đăng cái này lên PyPI, bất kỳ bản phân phối nào cũng có thể lấy nó từ đó. Cũng giống như một số làm với gói ruamel.yaml của tôi. Cảm ơn vì timenhận xét, tôi cập nhật câu trả lời
Anthon

5

Các tarlệnh giao dịch với hệ thống tập tin. Đầu vào của nó là một danh sách các tệp mà sau đó nó đọc từ một hệ thống tệp (bao gồm rất nhiều siêu dữ liệu). Bạn sẽ cần phải trình bày tệp zip dưới dạng một hệ thống tệp để tarlệnh đọc nó.

Hệ thống tệp ảo - AVFS sẽ cho phép mọi chương trình nhìn vào các tệp được lưu trữ hoặc nén thông qua giao diện hệ thống tệp tiêu chuẩn thông qua FUSE .

Có một số thông tin chi tiết trong readfs avfs-fuse và một số bản phân phối các gói cho nó.

Một bạn đã cài đặt AVFS, sau đó bạn có thể

mountavfs
cd ~/.avfs/path/to/somefile.zip#
tar -cvf /path/whatever.tar .

AVFS sẽ điền vào bất kỳ thông tin nào cho hệ thống tệp bị thiếu trong mã zip, như quyền sở hữu tệp, tar đó sẽ nhận.


0

Đây là một đoạn nhỏ chuyển đổi một kho lưu trữ ZIP thành một kho lưu trữ TAR.GZ phù hợp OnTheFly.

Chuyển đổi lưu trữ ZIP sang lưu trữ TAR một cách nhanh chóng

# File: zip2tar.py
#
# Convert ZIP archive to TAR.GZ archive.
#
# Written by Fredrik Lundh, March 2005.

# helpers (tweak as necessary)

def getuser():
    # return user name and user id
    return "anonymous", 1000

def getmode(name, data):
    # return mode ("b" or "t") for the given file.
    # you can do this either by inspecting the name, or
    # the actual data (e.g. by looking for non-ascii, non-
    # line-feed data).
    return "t" # assume everything's text, for now

#
# main

import tarfile
import zipfile

import glob, os, StringIO, sys, time

now = time.time()

user = getuser()

def fixup(infile):

    file, ext = os.path.splitext(infile)

    outfile = file + ".tar.gz"
    dirname = os.path.basename(file)

    print outfile

    zip = zipfile.ZipFile(infile, "r")

    tar = tarfile.open(outfile, "w:gz")
    tar.posix = 1

    for name in zip.namelist():

        if name.endswith("/"):
            continue

        data = zip.read(name)
        if getmode(name, data) == "t":
            data = data.replace("\r\n", "\n")

        tarinfo = tarfile.TarInfo()
        tarinfo.name = name
        tarinfo.size = len(data)
        tarinfo.mtime = now
        tarinfo.uname = tarinfo.gname = user[0]
        tarinfo.uid = tarinfo.gid = user[1]
        tar.addfile(tarinfo, StringIO.StringIO(data))

    tar.close()
    zip.close()

# convert all ZIP files in the current directory
for file in glob.glob("*.zip"):
    fixup(file)

Nguồn

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.