Comment obtenir les données de fin de l'archive gzip?

10

J'ai une archive gzip avec des données de fin. Si je le déballe en l'utilisant, gzip -dil me dit: " décompression OK, ordures restantes ignorées " (il en va de même pour gzip -tqui peut être utilisé comme méthode de détection de l'existence de telles données).

Maintenant, je voudrais faire connaissance avec ces ordures, mais curieusement, je n'ai trouvé aucun moyen de les extraire. gzip -l --verboseme dit que la taille "compressée" de l'archive est la taille du fichier (c'est-à-dire avec les données de fin), c'est faux et pas utile. fileest également d'aucune aide, alors que puis-je faire?

phk
la source

Réponses:

10

Compris maintenant comment obtenir les données de fin.

J'ai créé un script Perl qui crée un fichier avec les données de fin, il est fortement basé sur 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
la source
2
+1 mais IMO, l'impression sur stdout comme dans l'original (mais sans ajouter de nouvelle ligne) est préférable à l'écriture dans un nom de fichier codé en dur. Vous pouvez rediriger vers un fichier, ou diriger vers lessou hdou hd | lessou quoi que ce soit.
cas
@cas: Merci pour la contribution. Ajout d'un peu de gestion des paramètres maintenant. Mon premier script perl BTW, je savais que le moment viendrait un jour.
phk
1
belle amélioration. je voterais à nouveau si je pouvais :) une autre idée - un programme comme celui-ci n'a pas vraiment besoin d'un fichier d'entrée, il fonctionne tout aussi bien en traitant stdin. et une while (<>)boucle dans perllira stdin et tous les fichiers répertoriés dans @ARGV .... qui facilitent l'écriture de scripts qui fonctionnent aussi bien comme filtre (c.-à-d. lire stdin, écrire sur stdout) et avec les fichiers nommés ). et stdout, bien sûr, peut toujours être redirigé vers un fichier. la plupart de mes scripts Perl sont écrits sous forme de filtres pour en profiter.
cas
1
push @ARGV,'-' if (!@ARGV);avant, my $input_file_name = shift;c'est tout ce qui est nécessaire ici. c'est-à-dire un argument par défaut de -(le message d'aide pourrait être affiché si $ ARGV [0] == '-h' ou '--help'.). Pour une while(<>)boucle, vous n'auriez même pas besoin de le faire, mais c'est probablement plus difficile que d'écrire comme ça pour IO::Uncompress::Gunzip.
cas
2
C'est bon. et unshift au lieu de push a un sens pour la façon dont vous voulez l'utiliser, permet toujours de spécifier un nom de fichier de sortie comme seul argument. Je suis personnellement opposé à ce que les fichiers soient écrasés sans ordre explicite de l'utilisateur - redirection ou -ooption ou quelque chose. avoir un script basculer automatiquement du premier argument de deux en entrée au premier et seul l'argument en sortie me semble risqué et sujet aux accidents (tentant murphy).
cas