Convert tar.gz to zip

匿名 (未验证) 提交于 2019-12-03 08:48:34

问题:

I've got a large collection of gzipped archives on my Ubuntu webserver, and I need them converted to zips. I figure this would be done with a script, but what language should I use, and how would I go about unzipping and rezipping files?

回答1:

I'd do it with a bash(1) one-liner:

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 

It isn't very pretty because I'm not great at bash(1). Note that this destroys a lot of directories so be sure you know what this does before doing it.

See the bash(1) reference card for more details on the ${foo%bar} syntax.



回答2:

A simple bash script would be easiest, surely? That way you can just invoke the tar and zip commands.



回答3:

the easiest solution on unix platforms may well be to use fuse and something like archivemount (libarchive), http://en.wikipedia.org/wiki/Archivemount .

/iaw



回答4:

You can use node.js and tar-to-zip for this purpose. All you need to do is:

Install node.js with nvm if you do not have it.

And then install tar-to-zip with:

npm i tar-to-zip -g 

And use it with:

tarzip *.tar.gz 

Also you can convert .tar.gz files to .zip programmatically. You should install async and tar-to-zip locally:

npm i async tar-to-zip 

And then create converter.js with contents:

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


回答5:

Zipfiles are handy because they offer random access to files. Tar files only sequential.

My solution for this conversion is this shell script, which calls itself via tar(1) "--to-command" option. (I prefer that rather than having 2 scripts). But I admit "untar and zip -r" is faster than this, because zipnote(1) cannot work in-place, unfortunately.

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


回答6:

Here is a python solution based on this answer here:

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) 


文章来源: Convert tar.gz to zip
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!