Efektywna konwersja plików gzip do bzip2

10

Mam kilka plików gzip, które muszę od czasu do czasu konwertować na bzip2. Obecnie używam skryptu powłoki, który po prostu „gunzip's każdy plik, a następnie” bzip2 to. Chociaż to działa, to zajmuje dużo czasu.

Czy można uczynić ten proces bardziej wydajnym? Jestem gotów rzucić okiem i zajrzeć do kodów źródłowych gunzip i bzip2, jeśli to konieczne, ale chcę mieć pewność co do wypłaty. Czy jest jakaś nadzieja na poprawę wydajności procesu?

sundar - Przywróć Monikę
źródło

Odpowiedzi:

1

To pytanie zostało zadane dawno temu, gdy pbzip2 albo nie był dostępny, albo nie był w stanie kompresować ze standardowego wejścia, ale teraz możesz równolegle wykonywać kroki dekompresujące i kompresujące za pomocą programów równoległych i pbzip2 (zamiast bzip2 ):

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

co jest znacznie szybsze niż użycie bzip2 .

latający palec
źródło
Cześć, Zmieniłem zaakceptowaną odpowiedź na tę, ponieważ daje to najlepszą opcję dla osób, które dzisiaj napotykają to pytanie. Dzięki za pbzip2wzmiankę. Jeśli link nie ładuje się dla nikogo innego, oto strona projektu i strona man .
Sundar - Przywróć Monikę
15

Zamiast gunzip w jednym kroku i bzip2 w innym, zastanawiam się, czy bardziej efektywne byłoby użycie rur. Coś jakgunzip --to-stdout foo.gz | bzip2 > foo.bz2

Myślę z dwoma lub więcej procesorami, to zdecydowanie byłoby szybsze. Ale może nawet z jednym rdzeniem. Jednak ze wstydem przyznaję, że tego nie wypróbowałem.

ChrisInEdmonton
źródło
2
+1 za potokowanie, dyskowe we / wy to coś, czego chcesz uniknąć. Jeśli chodzi o kompresję, chyba że się mylę, bzip2 nie jest równoległy. Będziesz musiał użyć czegoś takiego jak pbzip2 do kompresji równolegle: kompresja.ca/pbzip2
gustafc
... i niestety wydaje się, że nie jest dostępne żadne narzędzie do dekompresji gzip równolegle.
gustafc
@gustafc: Dzięki za link do pbzip2, który był bardzo pomocny ... @OP: Unikałem przesyłania strumieniowego bcos Chcę mieć możliwość radzenia sobie z uszkodzonymi plikami GZ itp., nie tracąc ich w potoku ...
Sundar - Przywróć Monikę
4
@gustafc: Nawet jeśli bzip2i gzipnie działają równolegle wewnętrznie, za pomocą potoku możesz sprawić, aby działały równolegle, ponieważ potok domyślnie uruchamia dwa procesy, które będą działały równolegle. Tak więc przynajmniej dekompresja i kompresja będą działać równolegle.
śleske,
1
@sleske, nawet jeśli masz rację w teorii, bzip2użycie procesora przewyższa tę gunzip, więc w praktyce paralelizm, jaki tu osiągasz, jest minimalny. Mimo to nie trzeba wykonywać operacji dyskowych we / wy!
Johan Walles
6

GNU równoległy ( http://www.gnu.org/software/parallel ) może być opcją, jeśli masz wiele rdzeni (lub nawet wielu komputerów):

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

Przeczytaj stronę samouczka / podręcznika, aby uzyskać szczegółowe informacje i opcje.

supervlieg
źródło
3

To, co obecnie robisz, jest najlepszym wyborem. Nie ma dostępnego narzędzia do konwersji, a próba bzip2 już skompresowanego pliku nie jest tak naprawdę opcją, ponieważ często ma niepożądane skutki. Ponieważ algorytm jest inny, konwersja wymagałaby odzyskania oryginalnych danych niezależnie. Chyba że gzipping był krokiem w procesie bzip2, w którym niestety nie jest.

John T.
źródło
Nie algorytmy mają żadnych nakładających kroki takie, że mogę pominąć jeden krok w gzip dekompresji i to samo w bzip kompresji również?
Sundar - Przywróć Monikę
2
@sundar Nie sądzę. gzipużywa Leimpel-Ziv 77, a bzip2Burrows-Wheeler. Różne algorytmy, obawiam się.
new123456
2

Czasami muszę zrobić to samo z plikami dziennika. Najpierw zaczynam od najmniejszych plików * .gz ( ls -rS), gunzip, a następnie bzip2 osobno. Nie wiem, czy można skierować wyjście gunzip bezpośrednio na wejście bzip2. Polecenie bzip2 jest o wiele wolniejsze podczas kompresji niż gunzip podczas dekompresji, co może zajmować pamięć i zamieniać przestrzeń na hoście.

Ulepszenia lub sugestie są mile widziane. Oto mój jeden liniowiec:

for i in $(ls -rS *.gz | sed 's/\.gz//'); do gunzip ${i}.gz; bzip2 -9 ${i}; done
Mike L. Swartz
źródło
Dzięki za wkład, ważny jest punkt dotyczący różnicy prędkości między dwoma procesami i ich implikacji.
Sundar - Przywróć Monikę
1

Jeśli masz ich więcej, zapoznaj się z artykułem LJ z ładnym skryptem powłoki.

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

7zip ma lepszą kompresję i jest wielowątkowy.

Ronald Pottol
źródło
1

Musiałem to zrobić kilka minut temu:

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

Gdzie rezipbyłoby zdefiniowane jako:

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

Opcjonalnie możesz też zrobić to wielowątkowo, używając -Popcji z xargs, ale bądź ostrożny z tym. (Zacznij nisko!)

Brendan Byrd
źródło