¿Cómo obtener los datos finales del archivo gzip?


10

Tengo un archivo gzip con datos finales. Si lo descomprimo usando gzip -d, me dice: " descompresión OK, basura final ignorada " (lo mismo se gzip -tpuede usar como un método para detectar que existen tales datos).

Ahora me gustaría conocer esta basura, pero curiosamente no pude encontrar ninguna forma de extraerla. gzip -l --verboseme dice que el tamaño "comprimido" del archivo es el tamaño del archivo (es decir, con los datos finales), eso está mal y no es útil. filetampoco es de ayuda, entonces, ¿qué puedo hacer?

Respuestas:


10

Descubrí ahora cómo obtener los datos finales.

Creé el script Perl que crea un archivo con los datos finales, se basa en gran medida en 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";
}

2
+1 pero IMO, es mejor imprimir en stdout como en el original (pero sin agregar una nueva línea) que escribir en un nombre de archivo codificado. Puede redirigir a un archivo o una pipa a lesso hdo hd | lesso lo que sea.
cas

@cas: Gracias por el aporte. Se agregó un poco de manejo de parámetros ahora. Mi primer guión perl, por cierto, sabía que llegaría algún día.
phk

1
Buena mejora. Lo votaría de nuevo si pudiera :) una idea más: un programa como este realmente no necesita un archivo de entrada, funciona igual de bien procesando stdin. y un while (<>)bucle perlleerá stdin y cualquier archivo (s) enumerado en @ARGV ... eso hace que sea fácil escribir scripts que funcionen igual de bien como filtro (es decir, leer stdin, escribir en stdout) y con archivo (s) con nombre ) y stdout, por supuesto, siempre se pueden redirigir a un archivo. La mayoría de mis scripts de Perl están escritos como filtros para aprovechar esto.
cas

1
push @ARGV,'-' if (!@ARGV);antes my $input_file_name = shift;es todo lo que se necesita aquí. es decir, un argumento predeterminado de -(el mensaje de ayuda podría imprimirse si $ ARGV [0] == '-h' o '--help'.). Para un while(<>)bucle, ni siquiera necesitarías hacer eso, pero probablemente sea más problemático de lo que vale la pena escribirlo así IO::Uncompress::Gunzip.
cas

2
está bien. y unshift en lugar de push tiene sentido para la forma en que desea usarlo, todavía permite que se especifique un nombre de archivo de salida como el único argumento. Personalmente, soy reacio a que se sobrescriban los archivos sin un orden explícito del usuario: redirección o una -oopción o algo. hacer que un script cambie automáticamente de la primera arg de dos que se ingresa a la primera y que solo la salida de arg se muestra me parece arriesgada y propensa a accidentes (tentador murphy).
cas
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.