임시 디렉토리로 먼저 추출하지 않고 zip
아카이브를 아카이브 로 변환하는 방법이 tar
있습니까? (그리고 내 자신의 구현을 작성하지 않고도 tar
또는 unzip
)
답변
이제 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 파일보다 훨씬 작습니다. 압축 파일은 여러 파일에서 압축 패턴을 사용하지 않기 때문에 Bzip2 파일의 무언가가 잘못되면 이후 파일을 복구 할 가능성도 줄어 듭니다.
당신이 원하지 않는 경우 출력은, 제거, 압축 :bz2
및 .bz2
코드에서합니다.
pip
python3 환경에 설치 한 경우 다음을 수행 할 수 있습니다.
pip3 install ruamel.zip2tar
zip2tar
위의 작업을 수행 하는 명령 줄 유틸리티 를 얻습니다 (면책 조항 : 해당 패키지의 저자입니다).
답변
이 tar
명령은 파일 시스템을 처리합니다. 입력은 파일 시스템에서 읽은 파일 목록입니다 (많은 메타 데이터 포함). tar
명령 이 파일 을 읽으 려면 zip 파일을 파일 시스템으로 제공해야 합니다.
가상 파일 시스템-AVFS 를 사용하면 모든 프로그램이 FUSE 를 통해 표준 파일 시스템 인터페이스를 통해 아카이브 또는 압축 파일 내부를 볼 수 있습니다 .
avfs-fuse 추가 정보에 자세한 정보가 있으며 일부 배포판 에는 패키지 가 있습니다.
AVFS가 설치되어 있으면
mountavfs
cd ~/.avfs/path/to/somefile.zip#
tar -cvf /path/whatever.tar .
AVFS는 파일 소유권과 같이 zip에서 누락 된 파일 시스템에 대한 모든 정보를 tar가 가져옵니다.
답변
다음은 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)