Jak uzyskać końcowe dane archiwum gzip?


10

Mam archiwum gzip z końcowymi danymi. Jeśli go rozpakuję za pomocą gzip -d, powie mi: „ dekompresja OK, zignorowanie śmieci końcowych zignorowane ” (to samo dotyczy tego, gzip -tco można wykorzystać jako metodę wykrywania, że ​​takie dane są).

Teraz chciałbym poznać te śmieci, ale o dziwo nie mogłem znaleźć żadnego sposobu na ich wyodrębnienie. gzip -l --verbosemówi mi, że „skompresowany” rozmiar archiwum to rozmiar pliku (tj. z danymi końcowymi), to źle i nie jest pomocne. fileteż nie pomaga, więc co mogę zrobić?

Odpowiedzi:


10

Zrozumiałem teraz, jak uzyskać końcowe dane.

Stworzyłem skrypt Perla, który tworzy plik z końcowymi danymi, w dużej mierze oparty na 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, ale IMO, drukowanie na standardowym poziomie, jak w oryginale (ale bez dodawania nowego wiersza), jest lepsze niż pisanie na zakodowanej nazwie pliku. Można przekierować do pliku lub rury lessalbo hdalbo hd | lessalbo cokolwiek.
cas

@cas: Dziękujemy za wkład. Dodano teraz trochę obsługi parametrów. Mój pierwszy perlowy skrypt BTW, wiedziałem, że nadejdzie ten dzień.
phk

1
niezła poprawa. Chciałbym go jeszcze raz głosować, gdybym mógł :) Jeszcze jeden pomysł - program taki jak ten tak naprawdę nie potrzebuje pliku wejściowego, działa równie dobrze przetwarzając standardowe wejście. a while (<>)pętla perlodczyta stdin i wszystkie pliki wymienione w @ARGV ...., co ułatwia pisanie skryptów, które działają równie dobrze jak filtr (tj. odczytuje stdin, zapisuje na stdout) oraz z nazwanymi plikami ). i stdout, oczywiście, zawsze można przekierować do pliku. większość moich skryptów perla jest napisanych jako filtry, aby z tego skorzystać.
cas

1
push @ARGV,'-' if (!@ARGV);wcześniej my $input_file_name = shift;jest wszystko, co jest potrzebne tutaj. tzn. domyślny argument -(komunikat pomocy może zostać wydrukowany, jeśli $ ARGV [0] == '-h' lub '--help'.). W przypadku while(<>)pętli nie musisz nawet tego robić, ale prawdopodobnie jest to więcej kłopotów niż dla tego warto napisać IO::Uncompress::Gunzip.
cas

2
w porządku. i unshift zamiast push ma sens, jak chcesz go używać, nadal pozwala określić wyjściową nazwę pliku jako jedyny argument. Osobiście jestem przeciwny nadpisywaniu plików bez wyraźnego polecenia od użytkownika - przekierowania, -oopcji lub czegoś takiego. posiadanie skryptu w sposób automatyczny przełącza się z pierwszego argumentu dwóch wprowadzanych argumentów na pierwszy i tylko generowanie argumentu wydaje mi się ryzykowne i podatne na wypadki (kuszące morfiny).
cas
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.