Convert tar.gz to zip

I have a large collection of gzipped archives on my Ubuntu web server, and I need them to be converted to zip files. I suppose this will be done with a script, but what language should I use, and how can I start unpacking and unpacking files?

+4
source share
6 answers

I would do this with bash(1) single layer:

 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 is not very beautiful because I am not big in bash(1) . Note that this destroys many directories, so be sure to know what it does before you do it.

For more on the syntax of ${foo%bar} see the bash(1) help map .

+6
source

A simple bash script would be easiest of course? This way you can just invoke the tar and zip commands.

+2
source

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

/ IAW

+1
source

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

Install node.js with nvm if you don't have one.

And then install tar-to-zip with:

 npm i tar-to-zip -g 

And use it with:

 tarzip *.tar.gz 

You can also convert .tar.gz files to .zip programmatically. You must install async and tar-to-zip locally:

 npm i async tar-to-zip 

And then create converter.js with the content:

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

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

My solution for this conversion is a shell script that calls itself via the tar (1) "-to-command" parameter. (I prefer instead of 2 scripts). But I admit that "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 
0
source

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) 
0
source

All Articles