Có cách nào để chuyển đổi một zip
kho lưu trữ thành một tar
kho 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ề tar
hoặc unzip
)
Có cách nào để chuyển đổi một zip
kho lưu trữ thành một tar
kho 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ề tar
hoặc unzip
)
Câu trả lời:
Đ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 zip2tar
và làm cho nó thực thi hoặc lưu nó vào zip2tar.py
và 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.zip
sẽ 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
và .bz2
khỏi mã.
Nếu bạn đã pip
cài đặt trong môi trường python3, bạn có thể làm:
pip3 install ruamel.zip2tar
để có được một zip2tar
tiệ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 đó).
time
thiếu import
.
time
nhận xét, tôi cập nhật câu trả lời
Các tar
lệ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 để tar
lệ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á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.
Đâ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)