Як отримати остаточні дані архіву gzip?


10

У мене є gzip-архів із записом даних. Якщо я розпаковую його за допомогою gzip -dцього, він мені каже: " декомпресія в порядку, відмінне сміття ігнорується " (те саме стосується того, gzip -tякий можна використовувати як метод виявлення наявності таких даних).

Зараз я хотів би познайомитися з цим сміттям, але як не дивно, я не міг знайти жодного способу його видобути. gzip -l --verboseговорить мені, що "стиснутий" розмір архіву - це розмір файлу (тобто, з останніми даними), це неправильно і не корисно. fileтакож не допомагає, і що я можу зробити?

Відповіді:


10

Тепер з’ясували, як отримати дані про те,

Я створив сценарій Perl, який створює файл із кінцевими даними, він базується на 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, але IMO, друк у stdout як у оригіналі (але без додавання нового рядка) краще, ніж запис у жорстко закодоване ім’я файлу. Ви можете перенаправити в файл, або трубу lessабо hdабо hd | lessабо будь-який інший .
cas

@cas: Дякую за вклад. Зараз додано трохи обробки параметрів. Мій перший сценарій Perl BTW, я знав, що прийде час одного дня.
phk

1
приємне поліпшення. Я б схвалив його ще раз, якщо зможу :) Ще одна ідея - така програма, як це, насправді не потребує вхідного файлу, вона працює так само добре, як обробляє stdin. і while (<>)цикл perlбуде читати stdin та будь-який файл (и), вказаний у @ARGV ...., що дозволяє легко писати сценарії, які працюють однаково добре, як фільтр (тобто читати stdin, писати в stdout) та з іменованим файлом (ими) ). і stdout, звичайно, завжди можна переспрямувати у файл. більшість моїх сценаріїв Perl написані як фільтри, щоб скористатися цим.
cas

1
push @ARGV,'-' if (!@ARGV);перш ніж my $input_file_name = shift;тут все, що потрібно. тобто аргумент за замовчуванням -(довідкове повідомлення може бути надруковано, якщо $ ARGV [0] == '-h' або '--help'.). Для while(<>)циклу вам навіть не потрібно цього робити, але, мабуть, більше клопоту, ніж варто писати так IO::Uncompress::Gunzip.
cas

2
це добре. і невмикання замість push має сенс для того, як ви хочете його використовувати, все ще дозволяє вказати ім'я вихідного файлу як єдиний аргумент. Я особисто проти того, щоб файли перезаписувались без явного наказу користувача - перенаправлення чи -oопції чи чогось іншого. автоматичне переключення сценарію з першого аргументу з двох вхідних даних до першого та виведення лише аргументу для мене здається ризикованим та схильним до аварій (спокуслива морфія).
cas
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.