web-dev-qa-db-ja.com

ファイルシステムに抽出せずにZipをtarに変換する方法はありますか?

最初に一時ディレクトリに抽出せずにZipアーカイブをtarアーカイブに変換する方法はありますか? (そしてtarまたはunzipの独自の実装を書かずに)

17
user253751

これはPyPIからインストール可能なコマンドとして利用できるようになりました。この投稿の最後を参照してください。


そうする「標準」ユーティリティは知りませんが、この機能が必要なときに、次のように書きましたPythonスクリプトをZipからBzip2圧縮tarアーカイブに、ディスクに何も抽出せずに移動します最初:

#! /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)

Zip2tarに保存して実行可能にするか、Zip2tar.pyに保存してpython Zip2tar.pyを実行するだけです。スクリプトの引数としてZipファイル名を指定すると、xyz.Zipの出力ファイル名はxyz.tar.bz2になります。

Bzip2圧縮出力は通常、Zipファイルよりもはるかに小さくなります。これは、後者が複数のファイルに対して圧縮パターンを使用しないためです。ただし、Bzip2ファイル内の何かが間違っている場合、後のファイルを復元する可能性も低くなります。

出力を圧縮したくない場合は、コードから:bz2および.bz2を削除してください。


pipをpython3環境にインストールしている場合、次のことができます。

pip3 install ruamel.Zip2tar

上記のZip2tarコマンドラインユーティリティを取得するには(免責事項:私はそのパッケージの作成者です)。

12
Anthon

tarコマンドはファイルシステムを扱います。入力は、ファイルシステムから読み込まれるファイルのリストです(多くのメタデータを含む)。 tarコマンドで読み取るには、Zipファイルをファイルシステムとして提示する必要があります。

仮想ファイルシステム-AVFS を使用すると、すべてのプログラムで Fuse を使用して、標準のファイルシステムインターフェースを介してアーカイブファイルまたは圧縮ファイルを調べることができます。

avfs-Fuse readme およびいくつかの distributionshavepackages には、いくつかの詳細情報があります。

AVFSがインストールされている場合、次のことができます

mountavfs
cd ~/.avfs/path/to/somefile.Zip#
tar -cvf /path/whatever.tar .

AVFSは、tarが取得する、ファイルの所有権など、Zipにないファイルシステムの情報を入力します。

5
Matt

これは、Zipアーカイブを対応するTAR.GZアーカイブOnTheFlyに変換する小さなスニペットです。

その場でZipアーカイブをTARアーカイブに変換します

# 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)

ソース

0