Apakah ada cara untuk mengonversi zip
arsip ke tar
arsip tanpa mengekstraksi ke direktori sementara terlebih dahulu? (dan tanpa menulis implementasi saya sendiri tar
atau unzip
)
Apakah ada cara untuk mengonversi zip
arsip ke tar
arsip tanpa mengekstraksi ke direktori sementara terlebih dahulu? (dan tanpa menulis implementasi saya sendiri tar
atau unzip
)
Jawaban:
Ini sekarang tersedia sebagai perintah yang dapat diinstal dari PyPI, lihat akhir posting ini.
Saya tidak tahu ada utilitas "standar" yang melakukannya, tetapi ketika saya membutuhkan fungsionalitas ini, saya menulis skrip Python berikut untuk beralih dari ZIP ke Bzip2 arsip tar terkompresi tanpa mengekstraksi apa pun ke disk terlebih dahulu:
#! /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)
Hanya menyimpannya zip2tar
dan membuatnya dapat dieksekusi atau menyimpannya zip2tar.py
dan berjalan python zip2tar.py
. Berikan nama file ZIP sebagai argumen untuk skrip, nama file output xyz.zip
akan xyz.tar.bz2
.
Output terkompresi Bzip2 biasanya jauh lebih kecil daripada file zip karena yang terakhir tidak menggunakan pola kompresi lebih dari beberapa file, tetapi ada juga lebih sedikit peluang untuk memulihkan file kemudian jika ada sesuatu dalam file Bzip2 yang salah.
Jika Anda tidak ingin output dikompresi, hapus :bz2
dan .bz2
dari kode.
Jika Anda telah pip
menginstal di lingkungan python3, Anda dapat melakukan:
pip3 install ruamel.zip2tar
untuk mendapatkan zip2tar
utilitas commandline melakukan hal di atas (penafian: Saya adalah pembuat paket itu).
time
kekurangan import
.
time
komentarnya, saya memperbarui jawabannya
The tar
perintah berhubungan dengan file sistem. Inputnya adalah daftar file yang kemudian dibaca dari sistem file (termasuk banyak metadata). Anda perlu mempresentasikan file zip sebagai sistem file agar tar
perintah membacanya.
Sistem File Virtual - AVFS akan memungkinkan program apa pun untuk melihat ke dalam file yang diarsipkan atau dikompresi melalui antarmuka sistem file standar melalui FUSE .
Ada beberapa informasi terperinci dalam readfs-fuse readme dan beberapa distribusi memiliki paket untuk itu.
Satu Anda telah menginstal AVFS, maka Anda bisa
mountavfs
cd ~/.avfs/path/to/somefile.zip#
tar -cvf /path/whatever.tar .
AVFS akan mengisi semua informasi untuk sistem file yang hilang dari zip, seperti kepemilikan file, tar yang akan dijemput.
Berikut cuplikan kecil yang mengonversi arsip ZIP menjadi arsip TAR.GZ yang sesuai OnTheFly.
Ubah arsip ZIP menjadi arsip TAR dengan cepat
# 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)