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

9127
sundar

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

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

10

7 ответов на вопрос

15
ChrisInEdmonton

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

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

+1 для трубопровода, дисковый ввод-вывод - это то, чего вы хотите избежать. Что касается сжатия, то, если я не ошибаюсь, bzip2 - это не параллель. Вам придется использовать что-то вроде pbzip2 для сжатия в параллели: http://compression.ca/pbzip2/ gustafc 14 лет назад 2
... и, к сожалению, похоже, что нет никакой доступной утилиты распаковки параллели gzip. gustafc 14 лет назад 0
@gustafc: Спасибо за ссылку на pbzip2, это было очень полезно ... @OP: Я уклонился от бикинговой передачи, я хочу иметь возможность иметь дело с поврежденными файлами gz и т. д., не теряя их в канале ... sundar 14 лет назад 0
@gustafc: Даже если `bzip2` и` gzip` внутренне не работают параллельно, используя канал, вы можете заставить их работать параллельно, потому что канал неявно запускает два процесса, которые * будут * работать параллельно. Так что по крайней мере декомпрессия и сжатие будут выполняться параллельно. sleske 13 лет назад 4
@sleske, даже если вы правы в теории, использование процессора `bzip2` превосходит использование` gunzip`, поэтому на практике параллелизм, который вы здесь получаете, минимален. Не нужно делать дисковый ввод-вывод, все равно приятно! Johan Walles 6 лет назад 1
@JohanWalles: Да, но именно по этой причине _полезно, если параллелизация стала возможной благодаря каналу: если вместо этого сначала распаковать в файл, то bzip2, вы а) подвергаетесь дополнительному вводу / выводу (как уже упоминалось), и б) процессор не может даже начните работать над сжатием bzip2 до того, как будет сделан gunzip. Тот факт, что gunzip потребляет мало ресурсов процессора, является еще одной причиной, по которой bzip2 работает параллельно, поскольку в нем много простаивающих процессоров. sleske 6 лет назад 0
6
supervlieg

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

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

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

3
John T

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

Разве алгоритмы не имеют _any_ перекрывающихся шагов, чтобы я мог пропустить один шаг в распаковке gzip и то же самое в сжатии bzip? sundar 14 лет назад 0
@ sundar Я бы так не думал. `gzip` использует Leimpel-Ziv 77, а` bzip2` использует Burrows-Wheeler. Боюсь, разные алгоритмы. new123456 12 лет назад 2
2
Mike L Swartz

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

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

for i in $(ls -rS *.gz | sed 's/\.gz//'); do gunzip $.gz; bzip2 -9 $; done 
Спасибо за вклад, вопрос о разнице в скорости между этими двумя процессами и их значении является важным. sundar 11 лет назад 0
1
Ronald Pottol

Если у вас их несколько, прочитайте статью в ЖЖ с хорошим сценарием оболочки.

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

7zip получает лучшее сжатие, и является многопоточным.

1
Brendan Byrd

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

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

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

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

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

1
flyingfinger

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

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

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

Привет, я изменил принятый ответ на этот, так как это дает лучший вариант для людей, которые наткнулись на вопрос сегодня. Спасибо за упоминание `pbzip2`. В случае, если ссылка не загружается ни для кого другого, вот [страница проекта] (https://launchpad.net/pbzip2) и [страница man] (https://linux.die.net/man/1/). pbzip2). sundar 5 лет назад 0

Похожие вопросы