将tar.gz转换为zip

我在我的Ubuntunetworking服务器上有大量的gzip压缩文件,我需要把它们转换成zip文件。 我认为这将用脚本来完成,但是我应该使用什么语言,以及如何解压缩和重新压缩文件?

我会用bash(1)一行:

 for f in *.tar.gz;\ do rm -rf ${f%.tar.gz} ;\ mkdir ${f%.tar.gz} ;\ tar -C ${f%.tar.gz} zxvf $f ;\ zip -r ${f%.tar.gz} $f.zip ;\ rm -rf ${f%.tar.gz} ;\ done 

这不是很漂亮,因为我不是很棒bash(1) 。 请注意,这会破坏很多目录,因此请确保在执行此操作之前知道这是干什么的。

有关${foo%bar}语法的更多详细信息,请参阅bash(1)参考卡 。

一个简单的bash脚本将是最简单的,当然? 这样你就可以调用tarzip命令。

unix平台上最简单的解决方案很可能是使用fuse和类似archivemount(libarchive), http://en.wikipedia.org/wiki/Archivemount 。

/ IAW

您可以使用node.js和tar-to-zip来达到此目的。 所有你需要做的是:

如果没有,请用nvm安装node.js。

然后安装tar-to-zip

 npm i tar-to-zip -g 

和它一起使用:

 tarzip *.tar.gz 

您也可以通过编程将.tar.gz文件转换为.zip格式。 您应该在本地安装asynctar-to-zip

 npm i async tar-to-zip 

然后创建内容为converter.js

 #!/usr/bin/env node 'use strict'; const fs = require('fs'); const tarToZip = require('tar-to-zip'); const eachSeries = require('async/eachSeries'); const names = process.argv.slice(2); eachSeries(names, convert, exitIfError); function convert(name, done) { const {stdout} = process; const onProgress = (n) => { stdout.write(`\r${n}%: ${name}`); }; const onFinish = (e) => { stdout.write('\n'); done(); }; const nameZip = name.replace(/\.tar\.gz$/, '.zip'); const zip = fs.createWriteStream(nameZip) .on('error', (error) => { exitIfError(error); fs.unlinkSync(zipPath); }); const progress = true; tarToZip(name, {progress}) .on('progress', onProgress) .on('error', exitIfError) .getStream() .pipe(zip) .on('finish', onFinish); } function exitIfError(error) { if (!error) return; console.error(error.message); process.exit(1); } 

Zipfiles是方便的,因为它们提供对文件的随机访问。 Tar文件只有顺序。

这个转换的解决方案是这个shell脚本,它通过tar(1)“–to-command”选项调用它自己。 (我宁愿不要有2个脚本)。 但是我承认“untar和zip -r”比这个更快,因为zipnote(1)不能就地工作,不幸的是。

 #!/bin/zsh -feu ## Convert a tar file into zip: usage() { setopt POSIX_ARGZERO cat <<EOF usage: ${0##*/} [+-h] [-v] [--] {tarfile} {zipfile}" -v verbose -h print this message converts the TAR archive into ZIP archive. EOF unsetopt POSIX_ARGZERO } while getopts :hv OPT; do case $OPT in h|+h) usage exit ;; v) # todo: ignore TAR_VERBOSE from env? # Pass to the grand-child process: export TAR_VERBOSE=y ;; *) usage >&2 exit 2 esac done shift OPTIND-1 OPTIND=1 # when invoked w/o parameters: if [ $# = 0 ] # todo: or stdin is not terminal then # we are invoked by tar(1) if [ -n "${TAR_VERBOSE-}" ]; then echo $TAR_REALNAME >&2;fi zip --grow --quiet $ZIPFILE - # And rename it: # fixme: this still makes a full copy, so slow. printf "@ -\n@=$TAR_REALNAME\n" | zipnote -w $ZIPFILE else if [ $# != 2 ]; then usage >&2; exit 1;fi # possibly: rm -f $ZIPFILE ZIPFILE=$2 tar -xaf $1 --to-command=$0 fi 

这里是一个基于这个答案的Python解决方案:

 import sys, tarfile, zipfile, glob def convert_one_archive(file_name): out_file = file_name.replace('.tar.gz', '.zip') with tarfile.open(file_name, mode='r:gz') as tf: with zipfile.ZipFile(out_file, mode='a', compression=zipfile.ZIP_DEFLATED) as zf: for m in tf.getmembers(): f = tf.extractfile( m ) fl = f.read() fn = m.name zf.writestr(fn, fl) for f in glob.glob('*.tar.gz'): convert_one_archive(f)