C'è un modo per convertire un zip
archivio in un tar
archivio senza estrarlo prima in una directory temporanea? (e senza scrivere la mia implementazione di tar
o unzip
)
C'è un modo per convertire un zip
archivio in un tar
archivio senza estrarlo prima in una directory temporanea? (e senza scrivere la mia implementazione di tar
o unzip
)
Risposte:
Questo è ora disponibile come comando installabile da PyPI, vedere la fine di questo post.
Non conosco alcuna utility "standard" che lo faccia, ma quando avevo bisogno di questa funzionalità ho scritto il seguente script Python per passare dagli archivi tar compressi ZIP a Bzip2 senza estrarre prima nulla sul disco:
#! /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)
Basta salvarlo zip2tar
e renderlo eseguibile o salvarlo zip2tar.py
ed eseguirlo python zip2tar.py
. Fornire il nome del file ZIP come argomento per lo script, il nome del file di output per xyz.zip
sarà xyz.tar.bz2
.
L'output compresso di Bzip2 è normalmente molto più piccolo del file zip perché quest'ultimo non utilizza schemi di compressione su più file, ma c'è anche meno possibilità di recuperare il file successivo se qualcosa nel file Bzip2 è sbagliato.
Se non si desidera comprimere l'output, rimuovere :bz2
e .bz2
dal codice.
Se hai pip
installato in un ambiente python3, puoi fare:
pip3 install ruamel.zip2tar
per ottenere zip2tar
un'utilità da riga di comando che fa quanto sopra (dichiarazione di non responsabilità: sono l'autore di quel pacchetto).
time
manca un import
.
time
commento, aggiorno la risposta
Il tar
comando si occupa dei file system. Il suo input è un elenco di file che poi legge da un file system (inclusi molti metadati). Dovresti presentare il file zip come file system affinché il tar
comando lo legga.
Un file system virtuale - AVFS consentirà a qualsiasi programma di guardare all'interno di file archiviati o compressi tramite un'interfaccia di file system standard tramite FUSE .
Ci sono alcune informazioni dettagliate nel file Leggimi avfs-fuse e alcune distribuzioni hanno pacchetti per questo.
Uno su cui hai installato AVFS, quindi puoi farlo
mountavfs
cd ~/.avfs/path/to/somefile.zip#
tar -cvf /path/whatever.tar .
AVFS inserirà tutte le informazioni per il file system mancanti dallo zip, come la proprietà dei file, che tar raccoglierà.
Ecco un piccolo frammento che converte un archivio ZIP in un corrispondente archivio TAR.GZ OnTheFly.
Converti l'archivio ZIP in archivio TAR al volo
# 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)