GZIP-Dateien effizient in bzip2 konvertieren

9555
sundar

Ich habe eine Reihe von gzip-Dateien, die ich ab und zu in bzip2 konvertieren muss. Derzeit verwende ich ein Shellskript, das einfach jede Datei und dann bzz2 'gunzip'. Obwohl dies funktioniert, dauert es viel Zeit, um es abzuschließen.

Kann dieser Prozess effizienter gestaltet werden? Ich bin bereit, einen Tauchgang zu machen und mir ggf. die Quellcodes von gunzip und bzip2 anzuschauen, aber ich möchte nur sicher sein, dass es sich auszahlt. Gibt es Hoffnung, die Effizienz des Prozesses zu verbessern?

10

7 Antworten auf die Frage

15
ChrisInEdmonton

Anstelle von gunzip in einem Schritt und bzip2 in einem anderen, frage ich mich, ob es vielleicht effizienter wäre, Pipes zu verwenden. So etwas wiegunzip --to-stdout foo.gz | bzip2 > foo.bz2

Ich denke mit zwei oder mehr CPUs, das wäre definitiv schneller. Aber vielleicht sogar mit nur einem Kern. Ich gebe schändlich zu, dass ich das nicht ausprobiert habe.

+1 für Piping, Festplatten-E / A ist etwas, das Sie vermeiden möchten. Bezüglich der Komprimierung ist bzip2, wenn ich mich nicht irre, keine Parallele. Sie müssen etwas wie pbzip2 verwenden, um in parallell zu komprimieren: http://compression.ca/pbzip2/ gustafc vor 15 Jahren 2
... und leider scheint es kein parallell-gzip-Dekomprimierungsprogramm zu geben. gustafc vor 15 Jahren 0
@gustafc: Vielen Dank für den Link zu pbzip2, das war sehr hilfreich ... @OP: Ich habe mich vom Piping bcos abgewendet. Ich möchte mit korrupten gz-Dateien usw. umgehen können, ohne sie in der Pipe zu verlieren ... sundar vor 15 Jahren 0
@gustafc: Selbst wenn "bzip2" und "gzip" intern nicht parallel arbeiten, können Sie sie mithilfe einer Pipe parallel arbeiten lassen, da eine Pipe implizit zwei Prozesse startet, die * parallel laufen. Daher werden Dekompression und Komprimierung mindestens parallel ausgeführt. sleske vor 13 Jahren 4
@sleske, auch wenn Sie in der Theorie recht haben: Zwangsläufig stellt die CPU-Nutzung von "bzip2" den "gunzip" dar, also ist die Parallelität, die Sie hier erhalten, minimal. Disk IO nicht machen zu müssen ist trotzdem schön! Johan Walles vor 7 Jahren 1
@JohanWalles: Ja, aber aus genau diesem Grund ist die durch die Pipe ermöglichte Parallelisierung nützlich: Wenn Sie stattdessen zuerst dekomprimieren, dann gibt bzip2 a) zusätzliche E / A an (wie erwähnt) und b) die CPU nicht Sie können sogar mit der bzip2-Komprimierung arbeiten, bevor gunzip ausgeführt wird. Die Tatsache, dass gunzip nur wenig CPU benötigt, ist ein weiterer Grund, weshalb bzip2 parallel laufen soll, da viel CPU-Leerlauf verwendet werden muss. sleske vor 7 Jahren 0
6
supervlieg

GNU parallel ( http://www.gnu.org/software/parallel ) kann eine Option sein, wenn Sie über mehrere Kerne (oder sogar mehrere Maschinen) verfügen:

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

Lesen Sie die Tutorial- / Manpage für Details und Optionen.

3
John T

Was Sie gerade tun, ist Ihre beste Wette. Es gibt kein Konvertierungswerkzeug, und der Versuch, bzip2 eine bereits komprimierte Datei zu erstellen, ist keine Option, da dies häufig unerwünschte Auswirkungen hat. Da der Algorithmus unterschiedlich ist, würde das Konvertieren ungeachtet dessen das Abrufen der Originaldaten beinhalten. Außer wenn gzipping natürlich ein Schritt im bzip2-Prozess war, ist das leider nicht der Fall.

Haben die Algorithmen nicht _any_ überlappende Schritte, sodass ich einen Schritt in der gzip-Dekomprimierung und den gleichen in der bzip-Komprimierung überspringen könnte? sundar vor 15 Jahren 0
@sundar Das würde ich nicht glauben. "gzip" verwendet Leimpel-Ziv 77, "bzip2" Burrows-Wheeler. Ich fürchte, verschiedene Algorithmen. new123456 vor 13 Jahren 2
2
Mike L Swartz

Gelegentlich muss ich dasselbe mit Protokolldateien tun. Ich beginne mit den kleinsten * .gz-Dateien zuerst ( ls -rS), gunzip und dann und bzip2 sie einzeln. Ich weiß nicht, ob es möglich ist, den Ausgang gunzip direkt an den Eingang bzip2 zu leiten. Der bzip2-Befehl ist beim Komprimieren so viel langsamer als gunzip beim Dekomprimieren, dass er den Speicher und den Swap-Speicherplatz auf dem Host belegen kann.

Verbesserungen oder Vorschläge sind willkommen. Hier ist mein einziger Liner:

for i in $(ls -rS *.gz | sed 's/\.gz//'); do gunzip $.gz; bzip2 -9 $; done 
Vielen Dank für die Eingabe, der Punkt bezüglich der Geschwindigkeitsunterschiede zwischen den beiden Prozessen und ihrer Bedeutung ist wichtig. sundar vor 11 Jahren 0
1
Ronald Pottol

Wenn Sie mehr als nur wenige haben, lesen Sie den LJ-Artikel mit einem schönen Shell-Skript.

http://linuxgazette.net/123/bechtel.html

7zip verbessert die Komprimierung und ist mehrstufig.

1
Brendan Byrd

Just had to do this a few minutes ago:

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

Where rezip would be defined as:

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

Optionally, you can also make it multi-threaded by using a -P option with xargs, but be careful with that one. (Start low!)

1
flyingfinger

Diese Frage wurde vor langer Zeit gestellt, als pbzip2 entweder nicht verfügbar war oder nicht in der Lage war, aus stdin zu komprimieren, aber Sie können jetzt sowohl das Dekomprimieren als auch das Komprimieren mit parallel und pbzip2 (anstelle von bzip2 ) parallelisieren :

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

Das ist deutlich schneller als mit bzip2 .

Hallo, ich habe die akzeptierte Antwort auf diese Antwort geändert, da dies die beste Option für Leute darstellt, die heute über die Frage stolpern. Vielen Dank für die Erwähnung von "pbzip2". Falls der Link für niemanden anderen geladen wird, hier die [Projektseite] (https://launchpad.net/pbzip2) und die [manpage] (https://linux.die.net/man/1/). pbzip2). sundar vor 6 Jahren 0