Como obter dados finais do arquivo gzip?

10

Eu tenho um arquivo gzip com dados à direita. Se eu descompactá-lo usando, gzip -dele diz: " descompressão OK, lixo final ignorado " (o mesmo vale para o gzip -tqual pode ser usado como um método de detecção de que existem esses dados).

Agora eu gostaria de conhecer esse lixo, mas, estranhamente, não consegui encontrar nenhuma maneira de extraí-lo. gzip -l --verboseme diz que o tamanho "compactado" do arquivo morto é o tamanho do arquivo (isto é, com os dados à direita), isso é errado e não ajuda. filetambém não ajuda, então o que posso fazer?

phk
fonte

Respostas:

10

Descobri agora como obter os dados finais.

Eu criei o script Perl que cria um arquivo com os dados finais, é fortemente baseado em https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=604617#10 :

#!/usr/bin/perl
use strict;
use warnings; 

use IO::Uncompress::Gunzip qw(:all);
use IO::File;

unshift(@ARGV, '-') unless -t STDIN;

my $input_file_name = shift;
my $output_file_name = shift;

if (! defined $input_file_name) {
  die <<END;
Usage:

  $0 ( GZIP_FILE | - ) [OUTPUT_FILE]

  ... | $0 [OUTPUT_FILE]

Extracts the trailing data of a gzip archive.
Outputs to stdout if no OUTPUT_FILE is given.
- as input file file causes it to read from stdin.

Examples:

  $0 archive.tgz trailing.bin

  cat archive.tgz | $0

END
}

my $in = new IO::File "<$input_file_name" or die "Couldn't open gzip file.\n";
gunzip $in => "/dev/null",
  TrailingData => my $trailing;
undef $in;

if (! defined $output_file_name) {
  print $trailing;
} else {
  open(my $fh, ">", $output_file_name) or die "Couldn't open output file.\n";
  print $fh $trailing;
  close $fh;
  print "Output file written.\n";
}
phk
fonte
2
+1, mas IMO, imprimir em stdout como no original (mas sem anexar uma nova linha) é melhor do que gravar em um nome de arquivo codificado. Você pode redirecionar para um arquivo ou pipe para lessou hdou hd | lessou qualquer outra coisa.
cas
@cas: Obrigado pela contribuição. Adicionado um pouco de manipulação de parâmetros agora. Meu primeiro script perl BTW, eu sabia que chegaria a hora um dia.
Phd #
1
boa melhoria. eu iria votar novamente se eu pudesse :) mais uma idéia - um programa como esse realmente não precisa de um arquivo de entrada, ele funciona tão bem quanto o processamento de stdin. e um while (<>)loop in perlirá ler stdin e qualquer arquivo listado em @ARGV .... que facilita escrever scripts que funcionam igualmente bem como um filtro (por exemplo, ler stdin, gravar em stdout) e com o (s) arquivo (s) nomeado (s) ) e stdout, é claro, sempre pode ser redirecionado para um arquivo. a maioria dos meus scripts perl são escritos como filtros para tirar proveito disso.
14286
1
push @ARGV,'-' if (!@ARGV);antes my $input_file_name = shift;é tudo o que é necessário aqui. ou seja, um argumento padrão de -(a mensagem de ajuda pode ser impressa se $ ARGV [0] == '-h' ou '--help'.). Para um while(<>)loop, você nem precisaria fazer isso, mas provavelmente é mais complicado do que vale a pena escrever dessa maneira IO::Uncompress::Gunzip.
cas
2
está bem. e unshift em vez de push faz sentido para como você deseja usá-lo, ainda permite que um nome de arquivo de saída seja especificado como o único argumento. Pessoalmente, sou avesso a que os arquivos sejam substituídos sem uma ordem explícita do usuário - redirecionamento ou -oopção ou algo assim. ter um script alternar automaticamente do primeiro argumento arg de dois para o primeiro e somente do argumento parecer parecer arriscado e propenso a acidentes (tentador murphy).
16286