トレースデータを含むgzipアーカイブがあります。これを使用して開くと、gzip -d
次のように表示されます。解凍成功、末尾ガベージを無視(gzip -t
これらのデータが存在するかどうかを検出する方法としても使用できます.)
今、このゴミを理解したいのですが、奇妙なことに抽出する方法はありません。gzip -l --verbose
アーカイブの「圧縮された」サイズがファイルサイズ(つまり、末尾のデータを含む)であると言うのは間違っており、役に立ちません。file
何も役に立ちませんが、どうすればいいですか?
答え1
これで、追跡データを取得する方法を学びます。
私は末尾のデータを含むファイルを生成する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
gzipサイズを見つけるために小さなスクリプトを作成しました。
#!/bin/bash
set -e
gzip=${1:?Inform a gzip file}
size=$(stat -c%s "$gzip")
min=0
max=$size
while true; do
if head -c "$size" "$gzip" | gzip -v -t - &>/dev/null; then
echo $size
break
else
case "$?" in
1) min=$size ;;
2) max=$size ;;
esac
size=$(((max-min)/2 + min))
fi
done
その後、これを使用してgzipと末尾の部分を抽出できます。
file=gzip_with_trailing.gz
gzip_size=$(./find_gzip_size "$file")
head -c "$gzip_size" "$file" > data.gz
tail -c +$((1+gzip_size)) "$file" > trailing.raw
head/tailは最速のソリューションではありませんが、動作します。