有没有办法将zip
存档转换为tar
存档而无需先提取到临时目录? (并且没有编写我自己的tar
or实现unzip
)
答案1
现在可以从 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(tuple(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
执行上述操作的命令行实用程序(免责声明:我是该包的作者)。
答案2
该tar
命令处理文件系统。它的输入是文件列表,然后从文件系统读取该列表(包括大量元数据)。您需要将 zip 文件呈现为文件系统,以便命令tar
读取它。
虚拟文件系统 - AVFS将允许任何程序通过标准文件系统接口查看存档或压缩文件的内部保险丝。
里面有一些详细的信息avfs-fuse 自述文件还有一些分布 有 包为了它。
如果你安装了AVFS,那么你就可以
mountavfs
cd ~/.avfs/path/to/somefile.zip#
tar -cvf /path/whatever.tar .
AVFS 将填充 zip 中缺少的文件系统的任何信息,例如 tar 将拾取的文件所有权。
答案3
Linux 有一组很棒的工具,可以通过管道通过 stdin 和 stdout 进行工作。
unzip -p ./fzs-2015-03-18.zip | bzip2 > fzs-2015-03-18.bz
检查是否创建了临时文件
ps -ef | grep unzip
auser 44260 6666 3 11:18 pts/2 00:00:02 unzip -p ./fzs-2015-03-18.zip
auser 44434 44370 0 11:19 pts/1 00:00:00 grep --color=auto unzip
lsof -p 44260
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
unzip 44260 auser cwd DIR 259,6 4096 3015712 /home/auser/Documents/shares/logs
unzip 44260 auser rtd DIR 259,5 4096 2 /
unzip 44260 auser txt REG 259,5 178072 680357 /usr/bin/unzip
unzip 44260 auser mem REG 259,5 3040368 744942 /usr/lib/locale/locale-archive
unzip 44260 auser mem REG 259,5 2146832 666811 /usr/lib/libc-2.31.so
unzip 44260 auser mem REG 259,5 74440 751069 /usr/lib/libbz2.so.1.0.8
unzip 44260 auser mem REG 259,5 203056 665072 /usr/lib/ld-2.31.so
unzip 44260 auser 0u CHR 136,2 0t0 5 /dev/pts/2
unzip 44260 auser 1w FIFO 0,13 0t0 436437 pipe
unzip 44260 auser 2u CHR 136,2 0t0 5 /dev/pts/2
unzip 44260 auser 3r REG 259,6 513348882 3015900 /home/auser/Documents/shares/logs/fzs-2015-03-18.zip
ps -ef | grep bzip2
auser 44262 6666 99 11:18 pts/2 00:06:42 bzip2
auser 45111 44370 0 11:25 pts/1 00:00:00 grep --color=auto bzip2
⟩ lsof -p 44262
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bzip2 44262 auser cwd DIR 259,6 4096 3015712 /home/auser/Documents/shares/logs
bzip2 44262 auser rtd DIR 259,5 4096 2 /
bzip2 44262 auser txt REG 259,5 38744 655763 /usr/bin/bzip2
bzip2 44262 auser mem REG 259,5 2146832 666811 /usr/lib/libc-2.31.so
bzip2 44262 auser mem REG 259,5 74440 751069 /usr/lib/libbz2.so.1.0.8
bzip2 44262 auser mem REG 259,5 203056 665072 /usr/lib/ld-2.31.so
bzip2 44262 auser 0r FIFO 0,13 0t0 436437 pipe
bzip2 44262 auser 1w REG 259,6 97325056 3015902 /home/auser/Documents/shares/logs/fzs-2015-03-18.bz
bzip2 44262 auser 2u CHR 136,2 0t0 5 /dev/pts/2
只要管子|
,436437 pipe
超级简单。
您可以替换bzip2
为gzip
或其他一些通过 stdin 接受管道输入的实用程序
该 zip 文件包含数千个文本文件。
答案4
使用 libarchive 的bsdtar
:
bsdtar -zcf file.tar.gz @file.zip
来自手动的:
tar 创建并操作流归档文件。该实现可以从 tar、pax、cpio 中提取,压缩、jar、ar、xar、rpm、7-zip 和 ISO 9660 cdrom 映像,并可以创建柏油、pax、cpio、ar、zip、7-zip 和 shar 存档。
@archive
(c
仅限r
模式)指定的存档将被打开,其中的条目将被追加到当前存档中。举个简单的例子,tar -c -f - newfile @original.tar
将新存档写入标准输出,其中包含文件
newfile
和 中的所有条目original.tar
。相比之下,tar -c -f - newfile original.tar
创建一个只有两个条目的新存档。相似地,
tar -czf - --format pax @-
从标准输入读取存档(其格式将自动确定)并将其转换为标准输出上的 gzip 压缩的 pax 格式存档。 这样,tar 就可以用来将档案从一种格式转换为另一种格式。