Conversione efficiente di file gzip in bzip2


10

Ho un sacco di file gzip che devo convertire in bzip2 ogni tanto. Attualmente sto usando uno script di shell che semplicemente 'gunzip è ogni file e poi' bzip2 è tutto. Anche se funziona, ci vuole molto tempo per completarlo.

È possibile rendere questo processo più efficiente? Sono pronto a fare un tuffo e cercare i codici sorgente di gunzip e bzip2 se necessario, ma voglio solo essere sicuro del risultato. C'è qualche speranza di migliorare l'efficienza del processo?

Risposte:


1

Questa domanda è stata posta molto tempo fa quando pbzip2 non era disponibile o non era in grado di comprimere da stdin, ma ora è possibile parallelizzare sia i passaggi non compressi che quelli compressi utilizzando parallel e pbzip2 (anziché bzip2 ):

ls *.gz | parallel "gunzip -c {} | pbzip2 -c > {.}.bz2"

che è significativamente più veloce rispetto all'utilizzo di bzip2 .


Ciao, ho cambiato la risposta accettata a questa dato che questa offre la migliore opzione per le persone che si imbattono nella domanda oggi. Grazie per la pbzip2menzione. Nel caso in cui il collegamento non venga caricato per nessun altro, ecco la pagina del progetto e la pagina man .
Sundar - Ripristina Monica

15

Invece di gunzip in un passo e bzip2 in un altro, mi chiedo se sarebbe forse più efficiente usare le pipe. Qualcosa di simile agunzip --to-stdout foo.gz | bzip2 > foo.bz2

Sto pensando con due o più CPU, questo sarebbe sicuramente più veloce. Ma forse anche con un solo core. Ammetto vergognosamente di non averlo provato, però.


2
+1 per il piping, l'I / O del disco è qualcosa che vuoi evitare. Per quanto riguarda la compressione, a meno che non mi sbagli, bzip2 non è parallelo. Dovresti usare qualcosa come pbzip2 per comprimere in parallelo: compressione.ca/pbzip2
gustafc

... e sfortunatamente, non sembra esserci alcuna utilità di decompressione parallela gzip disponibile.
gustafc,

@gustafc: Grazie per il link a pbzip2, è stato molto utile ... @OP: Mi sono allontanato dai bc di piping, voglio essere in grado di gestire file gz corrotti, ecc., senza perderli nel tubo ...
Sundar - Ripristina Monica il

4
@gustafc: Anche se bzip2e gzipnon funzionano in parallelo internamente, usando una pipe puoi farle lavorare in parallelo, perché una pipe avvia implicitamente due processi, che verranno eseguiti in parallelo. Quindi almeno la decompressione e la compressione verranno eseguite in parallelo.
sleske,

1
@sleske, anche se in teoria hai ragione, bzip2l'uso della CPU sminuisce gunzipquello, quindi in pratica il parallelismo che ottieni qui è minimo. Non dover fare l'IO del disco è comunque bello!
Johan Walles,


3

Quello che stai attualmente facendo è la tua scommessa migliore. Non è disponibile uno strumento di conversione e il tentativo di bzip2 di un file già compresso non è in realtà un'opzione, poiché spesso ha effetti indesiderati. Poiché l'algoritmo è diverso, la conversione implicherebbe il recupero dei dati originali indipendentemente. A meno che ovviamente il gzipping non sia stato un passaggio nel processo bzip2, in cui purtroppo non lo è.


Non gli algoritmi hanno alcuna procedura sovrapposti tale da poter passare un passo in gzip decompressione e la stessa in bzip compressione anche?
Sundar - Ripristina Monica il

2
@sundar Non credo. gzipusa Leimpel-Ziv 77, mentre bzip2usa Burrows-Wheeler. Diversi algoritmi, temo.
nuovo123456,

2

Occasionalmente, devo fare la stessa cosa con i file di registro. Comincio con i file * .gz più piccoli prima ( ls -rS), gunzip e poi e bzip2 singolarmente. Non so se è possibile dirigere l'uscita gunzip direttamente sull'ingresso bzip2. Il comando bzip2 è molto più lento durante la compressione rispetto a Gunzip durante la decompressione che potrebbe consumare memoria e scambiare spazio sull'host.

Miglioramenti o suggerimenti sono i benvenuti. Ecco la mia unica fodera:

for i in $(ls -rS *.gz | sed 's/\.gz//'); do gunzip ${i}.gz; bzip2 -9 ${i}; done

Grazie per l'input, il punto sulla differenza di velocità tra i due processi e le sue implicazioni è importante.
Sundar - Ripristina Monica il


1

Ho dovuto farlo pochi minuti fa:

find . -name "*.gz" | perl -pi -e 's/\.gz$//g;' | xargs -n1 ./rezip

Dove rezipsarebbe definito come:

#!/bin/bash
gunzip -v $1.gz && bzip2 -9v $1

Facoltativamente, puoi anche renderlo multi-thread utilizzando -Pun'opzione con xargs, ma fai attenzione con quello. (Inizia in basso!)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.