Gibt es eine Möglichkeit, ein zip
Archiv in ein tar
Archiv zu konvertieren , ohne es zuerst in ein temporäres Verzeichnis zu extrahieren? (und ohne meine eigene Implementierung von tar
oder zu schreiben unzip
)
Gibt es eine Möglichkeit, ein zip
Archiv in ein tar
Archiv zu konvertieren , ohne es zuerst in ein temporäres Verzeichnis zu extrahieren? (und ohne meine eigene Implementierung von tar
oder zu schreiben unzip
)
Antworten:
Dies ist jetzt als installierbarer Befehl von PyPI verfügbar (siehe Ende dieses Beitrags).
Ich kenne kein "Standard" -Dienstprogramm, das dies tut, aber als ich diese Funktionalität benötigte, schrieb ich das folgende Python-Skript, um von ZIP zu Bzip2-komprimierten Tar-Archiven zu wechseln, ohne zuerst etwas auf die Festplatte zu extrahieren:
#! /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)
Einfach speichern zip2tar
und ausführbar machen oder speichern zip2tar.py
und ausführen python zip2tar.py
. Geben Sie den ZIP-Dateinamen als Argument für das Skript an. Der Ausgabedateiname für xyz.zip
lautet xyz.tar.bz2
.
Die komprimierte Ausgabe von Bzip2 ist normalerweise viel kleiner als die ZIP-Datei, da letztere keine Komprimierungsmuster für mehrere Dateien verwendet, aber es besteht auch eine geringere Wahrscheinlichkeit, dass eine spätere Datei wiederhergestellt wird, wenn etwas in der Bzip2-Datei nicht stimmt.
Wenn Sie die Ausgabe nicht komprimieren möchten, entfernen Sie :bz2
und .bz2
aus dem Code.
Wenn Sie pip
in einer python3-Umgebung installiert haben , können Sie Folgendes tun:
pip3 install ruamel.zip2tar
Um ein zip2tar
Kommandozeilen-Dienstprogramm zu erhalten, das die oben genannten Schritte ausführt (Haftungsausschluss: Ich bin der Autor dieses Pakets).
time
fehlt ein import
.
time
Kommentar, ich aktualisiere die Antwort
Der tar
Befehl behandelt Dateisysteme. Die Eingabe ist eine Liste von Dateien, die dann aus einem Dateisystem gelesen werden (einschließlich vieler Metadaten). Sie müssten die zip-Datei als Dateisystem präsentieren, damit der tar
Befehl sie lesen kann.
Ein virtuelles Dateisystem - Mit AVFS kann jedes Programm über eine standardmäßige Dateisystemschnittstelle über FUSE in archivierte oder komprimierte Dateien schauen .
Es gibt einige detaillierte Informationen in der Readme-Datei von avfs-fuse und einige Distributionen haben Pakete dafür.
Wenn Sie AVFS installiert haben, können Sie
mountavfs
cd ~/.avfs/path/to/somefile.zip#
tar -cvf /path/whatever.tar .
AVFS fügt alle Informationen für das Dateisystem ein, die in der ZIP-Datei fehlen, wie z. B. der Dateibesitz, den tar abholt.
Hier ist ein kleiner Ausschnitt, der ein ZIP-Archiv in ein passendes TAR.GZ-Archiv OnTheFly konvertiert.
Konvertieren Sie ZIP-Archiv in TAR-Archiv im laufenden Betrieb
# 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)