É possível converter 7z para tar diretamente?

10

Eu tenho um arquivo .7z contendo ~ 360.000 imagens em vários diretórios. Gostaria de convertê-lo em um .tar para que eu possa abri-lo em outro computador. Existe uma maneira melhor do que extraí-lo em arquivos e compactá-los novamente? É possível fazer a conversão diretamente?

Mohammad Moghimi
fonte
8
O que está impedindo você de abrir o .7zarquivo em outro computador?
Jordânia
Não tenho direitos de administrador no destino para instalar o 7z. Eu sei que posso instalar a partir de fonte etc ...
Mohammad Moghimi

Respostas:

8

Não é muito difícil escrever algo para fazer o trabalho. Aqui está um exemplo de script Perl (requer o módulo Archive :: Libarchive :: XS ).

#!/usr/bin/perl
use strict;
use warnings;
use Archive::Libarchive::XS qw(:all);

die "Usage: $0 in.7z out.tar" unless @ARGV == 2;
my ($infile, $outfile) = @ARGV;

my $in = archive_read_new();
archive_read_support_filter_none($in);
archive_read_support_format_7zip($in);

archive_read_open_filename($in, $infile, 10240) == ARCHIVE_OK
  or die "Error opening $infile: ", archive_error_string($in);

my $out = archive_write_new();
archive_write_set_format_ustar($out);
archive_write_open_filename($out, $outfile) == ARCHIVE_OK
  or die "Error opening $outfile: ", archive_error_string($out);

while (archive_read_next_header($in, my $entry) == ARCHIVE_OK) {
  archive_write_header($out, $entry) == ARCHIVE_OK
    or die archive_error_string($out);
  while (1) {
    my $size = archive_read_data($in, my $buff, 65536);
    die archive_error_string($in) if $size < 0; 
    last if $size == 0;
    archive_write_data($out, $buff) >= 0
      or die archive_error_string($out);
  }
} 

archive_read_free($in);
archive_write_close($out);
archive_write_free($out);

Se você queria um tar.gz / tar.bz2 / tar.xz arquivo, adicione a linha archive_write_add_filter_gzip($out);ou archive_write_add_filter_bzip2($out);ou archive_tar_add_filter_xz($out);depois da archive_write_set_formatlinha.

Isso não usa espaço em disco temporário (apenas o espaço para o arquivo tar de saída) e muito pouca RAM (apenas alguns MB para perl, mas funciona com os arquivos um bloco por vez, portanto, não há problema se os arquivos forem maiores que a sua RAM).

hobbs
fonte
15

.7zarquivos são arquivos frequentemente compactados com algum tipo de algoritmo, enquanto .tararquivos são apenas arquivos.

Eles diferem em seu escopo e, na maioria dos casos, uma conversão exigiria uma descompactação opcional sempre seguida de uma extração do arquivo de origem. Mesmo se um .7zarquivo não usasse nenhuma compactação, ainda assim exigiria uma extração.

Dito isto, se você pretendia [descompactar] / extrair / pesquisar o arquivo de origem de uma só vez, a resposta é que você não pode, pelo menos não usar as ferramentas padrão do Ubuntu porque tarnão pode lerstdin , então você não pode canalizar 7ze tar. De qualquer forma, é muito fácil automatizar tudo em um único comando:

mkdir tmp && 7z x <path_to_source_archive> -otmp && tar cf archive.tar tmp && rm -rf tmp

* <path_to_archive> = caminho para o .7zarquivo de origem

Além disso, o tempo necessário para que os arquivos do arquivo de origem sejam gravados no disco e para que os arquivos extraídos sejam lidos para descompactar / extrair / pesquisar o arquivo de origem em duas etapas é um gargalo para a tarefa inteira, principalmente (embora não somente) devido à baixa velocidade de E / S de um disco em potencial, portanto, uma solução parcial seria armazenar os arquivos temporários em um ramdisk para quase anular o gargalo geral:

  1. Crie o ponto de montagem para o sistema de arquivos do ramdisk: sudo mkdir /mnt/tmpfs
  2. Monte o sistema de arquivos do ramdisk: sudo mount -t tmpfs -o size=<tmpfs_size> tmpfs /mnt/ramdisk* <tmpfs_size> = tamanho do sistema de arquivos em bytes * 10 3 (1, 1K, 1M, 1G, ...)
  3. Execute mkdir /mnt/tmpfs/tmp && 7z x <path_to_source_archive> -o/mnt/tmpfs/tmp && tar cf archive.tar /mnt/tmpfs/tmp && rm -rf /mnt/tmpfs/tmp* <path_to_archive> = caminho para o .7zarquivo de origem
  4. Desmonte o sistema de arquivos do ramdisk: sudo umount
  5. Remova o ponto de montagem do sistema de arquivos do ramdisk: sudo rmdir /mnt/tmpfs
kos
fonte
Comentários não são para discussão prolongada; esta conversa foi movida para o bate-papo .
Mitch