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


17

最初に一時ディレクトリに抽出せずにzipアーカイブをアーカイブに変換する方法はありtarますか?(と私の独自の実装書き込みなしtarかをunzip


あなたは数えるくださいzipアーカイブをマウントファイルシステムにそれを抽出して?はいの場合、libarchiveで何も抽出せずに実行できますが、コーディングが必要です。
セラダ14

opは、このsuperuser.com/questions/325504/のようなものを探していると思います...それはあなたが達成したいと思っている種類のものですか?
vfbsilva 14

回答:


12

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


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

#! /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ファイルよりもはるかに小さくなります。後者は複数のファイルで圧縮パターンを使用しないためです。

あなたは出力が圧縮されたくない場合は、削除:bz2して.bz2コードから。


pippython3環境にインストールした場合、次のことができます。

pip3 install ruamel.zip2tar

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


1
良いですね。スクリプトは、ファイルの変更時間やアクセス許可などのメタデータをアーカイブ形式の変更全体にコピーしようとはしないようですが、簡単に追加できると思います。
セラダ14

@Celadaファイルの変更時間を追加しました(元のコードからコピーして貼り付けているときに欠落しました)、ZIP標準が実際に許可を持っているかどうかはわかりません。 。
アントン14

まさに私が探していたもの。このようなユーティリティが標準のUNIXパッケージから利用できると期待していました。これのライセンスは何ですか?おそらくいくつかの一般化の後、いくつかのパッケージ(たとえば、Debianのdevutils)に含めることを提案したいと思います。
rbrito

別のコメント:への参照にtimeはがありませんimport
rbrito

@rbritoこれをPyPIに投稿します。どんなディストリビューションでもそこから入手できます。ruamel.yamlパッケージを使用する場合と同様です。timeコメントをありがとう、答えを更新します
アントン

5

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

仮想ファイルシステム-AVFSは、FUSEを介した標準ファイルシステムインターフェイスを介して、あらゆるプログラムがアーカイブファイルまたは圧縮ファイルの内部を見ることができるようにします。

avfs-fuseのreadme詳細な情報があり、一部のディストリビューションに パッケージがあります

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

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

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


0

これは、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)

ソース

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.