Czy istnieje sposób na konwersję ziparchiwum do tararchiwum bez rozpakowywania go najpierw do katalogu tymczasowego? (i bez pisania własnej implementacji tarlub unzip)
Czy istnieje sposób na konwersję ziparchiwum do tararchiwum bez rozpakowywania go najpierw do katalogu tymczasowego? (i bez pisania własnej implementacji tarlub unzip)
Odpowiedzi:
To jest teraz dostępne jako polecenie instalacyjne z PyPI, patrz koniec tego postu.
Nie znam żadnego „standardowego” narzędzia, które to robi, ale kiedy potrzebowałem tej funkcji, napisałem następujący skrypt Pythona, aby przejść z archiwów tar skompresowanych do formatu Bzip2 bez rozpakowywania plików na dysk:
#! /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)
Po prostu zapisz go zip2tari zrób, aby był wykonywalny lub zapisz go zip2tar.pyi uruchom python zip2tar.py. Podaj nazwę pliku ZIP jako argument skryptu, a wyjściową nazwą pliku xyz.zipbędzie xyz.tar.bz2.
Skompresowane wyjście Bzip2 jest zwykle znacznie mniejsze niż plik zip, ponieważ ten drugi nie używa wzorców kompresji dla wielu plików, ale istnieje również mniejsze prawdopodobieństwo odzyskania późniejszego pliku, jeśli coś w pliku Bzip2 jest nieprawidłowe.
Jeśli nie chcesz wyjście kompresowane, zdjąć :bz2i .bz2od kodu.
Jeśli pipzainstalowałeś w środowisku python3, możesz:
pip3 install ruamel.zip2tar
aby uzyskać zip2tarnarzędzie wiersza polecenia, wykonujące powyższe czynności (wyłączenie odpowiedzialności: Jestem autorem tego pakietu).
timebraków import.
timekomentarz, aktualizuję odpowiedź
tarKomenda dotyczy systemów plików. Dane wejściowe to lista plików, które następnie odczytuje z systemu plików (w tym wiele metadanych). Aby tarkomenda mogła go odczytać, musisz przedstawić plik zip jako system plików .
Wirtualny system plików - AVFS pozwoli każdemu programowi zajrzeć do zarchiwizowanych lub skompresowanych plików za pośrednictwem standardowego interfejsu systemu plików za pomocą FUSE .
W pliku readme avfs-fuse znajduje się kilka szczegółowych informacji, a niektóre dystrybucje zawierają odpowiednie pakiety .
Jeśli masz zainstalowany system AVFS, możesz
mountavfs
cd ~/.avfs/path/to/somefile.zip#
tar -cvf /path/whatever.tar .
System AVFS wypełni wszelkie informacje dotyczące systemu plików, których brakuje w pliku zip, takie jak prawo własności do pliku, które tar pobierze.
Oto mały fragment, który konwertuje archiwum ZIP do pasującego archiwum TAR.GZ OnTheFly.
Konwertuj archiwum ZIP do archiwum TAR w locie
# 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)