วิธีรับข้อมูลต่อท้ายของไฟล์เก็บถาวร gzip?


10

ฉันมีไฟล์เก็บถาวร gzip ที่มีข้อมูลต่อท้าย ถ้าฉันแกะมันโดยใช้gzip -dมันบอกฉันว่า: " decompression OK, trailing garbage ละเว้น " (เหมือนกับการไป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) และด้วยชื่อไฟล์ (s) ) และ stdout แน่นอนสามารถเปลี่ยนเส้นทางไปยังไฟล์ได้เสมอ สคริปต์ Perl ส่วนใหญ่ของฉันเขียนเป็นตัวกรองเพื่อใช้ประโยชน์จากสิ่งนี้
cas

1
push @ARGV,'-' if (!@ARGV);ก่อนหน้าmy $input_file_name = shift;นี้เป็นสิ่งที่ต้องการที่นี่ เช่น ARG เริ่มต้นของ-(ข้อความช่วยเหลือสามารถพิมพ์ถ้า $ ARGV [0] == '-h' หรือ '--help'.) สำหรับwhile(<>)วงที่คุณจะไม่จำเป็นต้องแม้จะทำอย่างนั้น IO::Uncompress::Gunzipแต่มันก็อาจจะเป็นปัญหามากกว่าก็คุ้มค่าที่จะเขียนมันเหมือนว่า
cas

2
ทุกอย่างปกติดี. และ unshift แทนการกดทำให้รู้สึกว่าคุณต้องการใช้ยังคงช่วยให้ระบุชื่อไฟล์ที่ส่งออกเป็น ARG เดียวเท่านั้น ฉันไม่ชอบที่จะเขียนทับไฟล์ส่วนตัวโดยไม่ได้รับคำสั่งจากผู้ใช้อย่างชัดเจน - การเปลี่ยนเส้นทางหรือ-oตัวเลือกหรือบางสิ่งบางอย่าง การมีสคริปต์โดยอัตโนมัติสลับจาก ARG แรกของทั้งสองเข้าเป็นแรกและเพียง ARG ออกดูเหมือนว่ามีความเสี่ยงและอุบัติเหตุได้ง่ายสำหรับฉัน (ดึงดูดเมอร์ฟี่)
cas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.