Convertendo arquivos gzip para bzip2 eficientemente

9

Eu tenho um monte de arquivos gzip que eu tenho que converter para bzip2 de vez em quando. Atualmente, estou usando um script de shell que simplesmente 'gunzip cada arquivo e, em seguida,' bzip2 é isso. Embora isso funcione, leva um lote de tempo para ser concluído.

É possível tornar esse processo mais eficiente? Estou pronto para dar um mergulho e olhar para os códigos-fonte do gunzip e do bzip2, se necessário, mas eu só quero ter certeza da recompensa. Existe alguma esperança de melhorar a eficiência do processo?

    
por sundar 17.08.2009 / 02:45

7 respostas

1

Essa pergunta foi feita há muito tempo, quando o pbzip2 não estava disponível ou não era capaz de compactar a partir de stdin, mas você agora pode paralelizar etapas de descompressão e compactação usando o paralelo e pbzip2 (em vez de bzip2 ):

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

que é significativamente mais rápido do que usar o bzip2 .

    
por 06.12.2017 / 21:58
15

Em vez de gunzip em um passo e bzip2 em outro, eu me pergunto se seria talvez mais eficiente usar canos. Algo como gunzip --to-stdout foo.gz | bzip2 > foo.bz2

Estou pensando em dois ou mais CPUs, isso definitivamente seria mais rápido. Mas talvez até com apenas um único núcleo. Eu vergonhosamente admito não ter tentado isso, no entanto.

    
por 17.08.2009 / 05:17
6

O paralelo GNU ( link ) pode ser uma opção se você tiver vários núcleos (ou até mesmo várias máquinas):

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

Leia a página tutorial / man para detalhes e opções.

    
por 05.03.2014 / 17:11
3

O que você está fazendo atualmente é a sua melhor aposta. Não há nenhuma ferramenta de conversão disponível, e tentar bzip2 um arquivo já gzipado não é realmente uma opção, já que freqüentemente tem efeitos indesejáveis. Como o algoritmo é diferente, a conversão envolveria recuperar os dados originais independentemente. A menos que, claro, o gzip fosse um passo no processo do bzip2, no qual não é infelizmente.

    
por 17.08.2009 / 03:13
2

Ocasionalmente, eu preciso fazer a mesma coisa com arquivos de log. Eu começo com os arquivos * .gz menores primeiro ( ls -rS ), gunzip e depois e bzip2 individualmente. Eu não sei se é possível direcionar a saída do gunzip diretamente para a entrada do bzip2. O comando bzip2 é muito mais lento na compactação do que o gunzip na descompressão, o que pode consumir a memória e trocar espaço no host.

Melhorias ou sugestões são bem vindas. Aqui está o meu um forro:

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

Se você tiver mais do que alguns, confira o artigo do LJ com um bom shell script.

link

O 7zip obtém melhor compactação e é multiencadeado.

    
por 07.01.2010 / 03:13
1

Só tive que fazer isso alguns minutos atrás:

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

Em que rezip seria definido como:

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

Opcionalmente, você também pode torná-lo multi-threaded usando uma opção -P com xargs , mas tenha cuidado com isso. (Comece baixo!)

    
por 01.11.2012 / 13:06