Конвертировать tar.gz в zip - PullRequest
6 голосов
/ 10 июня 2011

У меня есть большая коллекция сжатых архивов на моем веб-сервере Ubuntu, и мне нужно, чтобы они были преобразованы в почтовые индексы.Я полагаю, что это будет сделано с помощью скрипта, но какой язык мне использовать, и как мне распаковать и разархивировать файлы?

Ответы [ 6 ]

6 голосов
/ 10 июня 2011

Я бы сделал это с 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).Обратите внимание, что это уничтожает множество каталогов, поэтому убедитесь, что вы знаете, что это делает, прежде чем делать это.

См. справочную карту bash(1) для получения дополнительной информации о синтаксисе ${foo%bar}.

2 голосов
/ 10 июня 2011

Простой bash-скрипт будет проще, не правда ли? Таким образом, вы можете просто вызывать команды tar и zip.

1 голос
/ 04 сентября 2014

простейшим решением на платформах Unix вполне может быть использование fuse и что-то вроде archivemount (libarchive), http://en.wikipedia.org/wiki/Archivemount.

/ iaw

0 голосов
/ 12 мая 2017

Вот решение 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)
0 голосов
/ 28 января 2017

Zip-файлы удобны, потому что они предлагают произвольный доступ к файлам.Файлы tar только последовательные.

Мое решение для этого преобразования - это сценарий оболочки, который вызывает себя через опцию tar (1) «--to-command».(Я предпочитаю это, а не иметь 2 сценария).Но я допускаю, что «untar and 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
0 голосов
/ 05 ноября 2016

Вы можете использовать node.js и tar-to-zip для этой цели. Все, что вам нужно сделать, это:

Установите файл node.js с nvm , если у вас его нет.

А затем установите tar-to-zip с помощью:

npm i tar-to-zip -g

И используйте его с:

tarzip *.tar.gz

Также вы можете программно конвертировать .tar.gz файлы в .zip. Вы должны установить async и tar-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);
}
...