Эффективное преобразование файлов gzip в bzip2


10

У меня есть куча gzip-файлов, которые я должен время от времени конвертировать в bzip2. В настоящее время я использую сценарий оболочки, который просто 'gunzip' каждый файл, а затем 'bzip2 его. Хотя это работает, для завершения требуется много времени.

Можно ли сделать этот процесс более эффективным? Я готов совершить погружение и посмотреть исходные коды gunzip и bzip2, если это необходимо, но я просто хочу быть уверен в выигрыше. Есть ли надежда на повышение эффективности процесса?

Ответы:


1

Этот вопрос задавался давным-давно, когда pbzip2 либо не был доступен, либо не был способен сжимать из stdin, но теперь вы можете распараллеливать и распаковывать, и сжимать шаги, используя параллельный и pbzip2 (вместо bzip2 ):

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

что значительно быстрее, чем при использовании bzip2 .


Привет, я изменил принятый ответ на этот, так как это дает лучший вариант для людей, спотыкающихся в вопросе сегодня. Спасибо за pbzip2упоминание. В случае , если ссылка не сработал ни для кого другого, вот страница проекта и страница человека .
sundar - Восстановить Монику

15

Интересно, а не gunzip на одном шаге и bzip2 на другом, было бы более эффективно использовать трубы. Что-то типаgunzip --to-stdout foo.gz | bzip2 > foo.bz2

Я думаю, с двумя или более процессорами, это определенно будет быстрее. Но, возможно, даже с одним ядром. Я позорно признаюсь, что не испытал это, все же.


2
+1 для трубопровода, дисковый ввод-вывод - это то, чего вы хотите избежать. Что касается сжатия, то, если я не ошибаюсь, bzip2 - это не параллель. Вы должны были бы использовать что - то вроде pbzip2 для компресса в parallell: compression.ca/pbzip2
gustafc

... и, к сожалению, похоже, что нет никакой доступной утилиты распаковки параллели gzip.
gustafc

@gustafc: Спасибо за ссылку на pbzip2, это было очень полезно ... @OP: Я уклонился от передачи bcos-файлов, я хочу иметь возможность иметь дело с поврежденными файлами gz и т. д., не теряя их в канале ...
sundar - Восстановить Монику

4
@gustafc: Даже если внутренне bzip2и gzipне работать параллельно, используя канал, вы можете заставить их работать параллельно, потому что канал неявно запускает два процесса, которые будут работать параллельно. Так что по крайней мере декомпрессия и сжатие будут выполняться параллельно.
слеске

1
@sleske, даже если вы правы в теории, bzip2использование ЦП превосходит его gunzip, поэтому на практике получаемый здесь параллелизм минимален. Не нужно делать дисковый ввод-вывод, все равно приятно!
Йохан Уоллес

6

Параллельная версия GNU ( http://www.gnu.org/software/parallel ) может быть полезна, если у вас несколько ядер (или даже несколько машин):

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

Прочитайте учебник / справочную страницу для деталей и опций.


3

То, что ты сейчас делаешь, - твоя лучшая ставка. Нет доступных инструментов для конвертации, и попытка bzip2 уже сжатого gzip-файла на самом деле не вариант, так как он часто имеет нежелательные эффекты. Поскольку алгоритм отличается, преобразование будет включать в себя извлечение исходных данных независимо. Если, конечно, gzipping не был шагом в процессе bzip2, к сожалению, это не так.


Не алгоритмы имеют каких - либо перекрывающихся такие шаги , которые я мог бы пропустить один шаг в Gzip декомпрессия и то же самое в BZIP сжатия также?
sundar - Восстановить Монику

2
@ sundar Я бы так не думал. gzipиспользует Leimpel-Ziv 77, в то время как bzip2использует Burrows-Wheeler. Боюсь, разные алгоритмы.
new123456

2

Иногда мне нужно делать то же самое с файлами журналов. Сначала я начинаю с самых маленьких файлов * .gz ( ls -rS), gunzip, а затем и bzip2 по отдельности. Я не знаю, можно ли направить выход gunzip непосредственно на вход bzip2. Команда bzip2 намного медленнее при сжатии, чем gunzip при распаковке, что может потреблять память и пространство подкачки на хосте.

Улучшения или предложения приветствуются. Вот мой единственный вкладыш:

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

Спасибо за вклад, вопрос о разнице в скорости между этими двумя процессами и их значении является важным.
sundar - Восстановить Монику


1

Просто пришлось сделать это несколько минут назад:

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

Где rezipбудет определяться как:

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

При желании вы также можете сделать его многопоточным, используя -Pопцию с xargs, но будьте осторожны с этим. (Начните с низкого!)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.