จะคลายการบีบอัดข้อมูล zlib ใน UNIX ได้อย่างไร


106

ฉันได้สร้างข้อมูลที่บีบอัด zlib ใน Python แล้วดังนี้

import zlib
s = '...'
z = zlib.compress(s)
with open('/tmp/data', 'w') as f:
    f.write(z)

(หรือหนึ่งซับในเปลือก: echo -n '...' | python2 -c 'import sys,zlib; sys.stdout.write(zlib.compress(sys.stdin.read()))' > /tmp/data)

ตอนนี้ฉันต้องการคลายการบีบอัดข้อมูลในเชลล์ ทั้งzcatมิได้uncompressทำงาน:

$ cat /tmp/data | gzip -d -
gzip: stdin: not in gzip format

$ zcat /tmp/data 
gzip: /tmp/data.gz: not in gzip format

$ cat /tmp/data | uncompress -
gzip: stdin: not in gzip format

ดูเหมือนว่าฉันจะสร้างไฟล์เหมือน gzip แต่ไม่มีส่วนหัวใด ๆ น่าเสียดายที่ฉันไม่เห็นตัวเลือกใด ๆ ในการคลายการบีบอัดข้อมูลดิบในหน้า man ของ gzip และแพ็คเกจ zlib นั้นไม่มียูทิลิตี้ที่สามารถใช้งานได้

มียูทิลิตี้ในการคลายบีบอัดข้อมูลดิบ zlib หรือไม่?


มีคำตอบเพิ่มเติมอีกมากมายที่นี่: stackoverflow.com/questions/3178566/deflate-command-line-tool
Jack O'Connor

คำตอบ:


140

นอกจากนี้ยังเป็นไปได้ที่จะแตกไฟล์โดยใช้ + ถ้าคุณไม่มีหรือต้องการใช้หรือเครื่องมืออื่น ๆ
เคล็ดลับคือการเพิ่มหมายเลขมายากล gzip และวิธีการบีบอัดข้อมูลจริงจากzlib.compress:

printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" |cat - /tmp/data |gzip -dc >/tmp/out

การแก้ไข:
@ d0sboots แสดงความคิดเห็น: สำหรับข้อมูล RAW Deflate คุณต้องเพิ่ม 2 ไบต์ที่ว่างอีก:
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00"

Q on SOนี้ให้ข้อมูลเพิ่มเติมเกี่ยวกับวิธีการนี้ คำตอบนั้นแสดงให้เห็นว่ามีส่วนท้าย 8 ไบต์เช่นกัน

Users @ Vitali-Kushner และ @ mark-bessey รายงานความสำเร็จแม้จะถูกตัดทอนไฟล์ดังนั้นส่วนท้ายของ gzip จึงไม่จำเป็นต้องใช้อย่างเคร่งครัด

@ tobias-kienzler แนะนำฟังก์ชันนี้สำหรับ :
zlipd() (printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" |cat - $@ |gzip -dc)


gzip ไม่ทำงาน แต่ zlib-flate ทำ (สตรีมเนื้อหาหน้า pdf)
Daneel S. Yaitskov

69

ผู้ใช้ @tino แสดงความคิดเห็นด้านล่างคำตอบ OpenSSL แต่ฉันคิดว่าสิ่งนี้ควรแยกจากกัน:

zlib-flate -uncompress < FILE

ฉันลองสิ่งนี้และมันก็ได้ผลสำหรับฉัน

zlib-flateสามารถพบได้ในแพ็คเกจqpdf(ใน Debian Squeeze และ Fedora 23 ตามความคิดเห็นในคำตอบอื่น ๆ )


3
ตรงกันข้ามกับคำตอบอื่น ๆ อันนี้ใช้ได้กับ OS X
polym

2
@polym คุณzlib-flate ติดตั้งบน macOS ได้อย่างไร ฉันไม่เห็นมันทุกที่
Wildcard

4
@ Wildcard ขออภัยสำหรับการตอบกลับล่าช้า ฉันคิดว่ามันมาพร้อมกับqpdfแพ็คเกจที่ฉันติดตั้งด้วยbrewตามที่ระบุไว้ในความคิดเห็นด้านบน - หรือดูประโยคสุดท้ายของคำตอบนี้ :) นอกจากนี้ยังqpdfเจ๋งจริงๆดังนั้นดูด้วยถ้าคุณมีเวลา!
polym

ชงติดตั้ง qpdf จากนั้นคำสั่งที่ระบุไว้ข้างต้น :-) ขอบคุณ!
Fernando Gabrieli

60

ฉันพบวิธีแก้ไขปัญหา (หนึ่งในวิธีที่เป็นไปได้) กำลังใช้openssl :

$ openssl zlib -d < /tmp/data

หรือ

$ openssl zlib -d -in /tmp/data

* หมายเหตุ: ฟังก์ชั่น zlib มีให้บริการในรุ่น openssl ล่าสุด> = 1.0.0 (OpenSSL จะต้องมีการกำหนดค่า / สร้างด้วยตัวเลือก zlib หรือ zlib-dynamic ตัวหลังเป็นค่าเริ่มต้น)


25
ใน Debian Squeeze (ซึ่งมี OpenSSL 0.9.8) มีอยู่zlib-flateในqpdfแพ็คเกจ zlib-flate -uncompress < FILEมันสามารถนำมาใช้เช่น
Tino

7
zlib ถูกลบออกจาก OpenSSL เวอร์ชันล่าสุดดังนั้นเคล็ดลับนี้มีประโยชน์มาก @Tino
Alexandr

1
ขอบคุณ วิธีนี้ให้ประสบการณ์ที่ดีกว่าในการคลายการบีบอัดไฟล์อินพุตสั้นกว่าคำตอบโดยใช้ "gzip" ("openssl" คลายการบีบอัดให้มากที่สุดในขณะที่ "gzip" ยกเลิกการพิมพ์ "สิ้นสุดไฟล์ที่ไม่คาดคิด")
Daniel K.

2
@ ติโนนี่ควรเป็นคำตอบที่แยกจากกัน
Catskul

1
@ ติโน่, มันยังมีให้บริการผ่านแพ็คเกจ qpdf บน Fedora 23. Alexandr Kurilin, zlib ยังคงมีให้ใน 1.0.2d-fips.
maxschlepzig

28

ฉันแนะนำpigzจากMark Adlerผู้เขียนร่วมของไลบรารีการบีบอัด zlib ดำเนินการpigzเพื่อดูธงที่มีอยู่

คุณจะสังเกตเห็น:

-z --zlib Compress to zlib (.zz) instead of gzip format.

คุณสามารถคลายการบีบอัดโดยใช้-dธง:

-d --decompress --uncompress Decompress the compressed input.

สมมติว่าไฟล์ชื่อ 'ทดสอบ':

  • pigz -z test - สร้างไฟล์บีบอัด zlib ชื่อ test.zz
  • pigz -d -z test.zz - แปลง test.zz เป็นไฟล์ทดสอบที่คลายการบีบอัด

บน OSX คุณสามารถดำเนินการได้ brew install pigz


7
หาดี! ดูเหมือนว่าจะสามารถตรวจจับไฟล์ zlib ได้ด้วยตัวเองดังนั้นunpigz test.zzจะทำงานได้ดี
Stéphane Chazelas

ไม่ได้ขยายข้อมูลของฉัน
ไซเบอร์นาร์ด

1
@cybernard คุณอาจไม่มีไฟล์ zlib ตรวจสอบกับ:$>file hello.txt.zz hello.txt.zz: zlib compressed data
snodnipper

11

zlibใช้การบีบอัดที่ใช้โดย gzip แต่ไม่ใช่รูปแบบไฟล์ คุณควรใช้gzipโมดูลที่ตัวมันเองใช้zlibแทน

import gzip
s = '...'
with gzip.open('/tmp/data', 'w') as f:
    f.write(s)

ตกลง แต่สถานการณ์ของฉันคือฉันมีไฟล์เหล่านี้สร้างขึ้นเป็นหมื่น / แสนดังนั้น .. :)

1
ดังนั้น ... ไฟล์ของคุณไม่สมบูรณ์ บางทีคุณอาจต้องคลายการบีบอัดzlibและบีบอัดgzipอีกครั้งหากคุณยังไม่มีข้อมูลต้นฉบับ
เกร็กฮิวกิล

6
@mykhal ทำไมคุณสร้างไฟล์หมื่น / แสนไฟล์ก่อนที่จะตรวจสอบว่าคุณสามารถคลายการบีบอัดได้จริงหรือ?

3
harpyon ฉันสามารถยกเลิกการบีบอัดพวกเขาฉันเพียงแค่สงสัยว่าน้อยกว่าหรือ urility หรือการตั้งค่า zgip ร่วมกันมากขึ้นสามารถใช้สำหรับว่าถ้าฉันไม่ต้องการที่จะทำมันในหลามอีกครั้ง

3

สิ่งนี้อาจทำ:

import glob
import zlib
import sys

for filename in sys.argv:
    with open(filename, 'rb') as compressed:
        with open(filename + '-decompressed', 'wb') as expanded:
            data = zlib.decompress(compressed.read())
            expanded.write(data)

จากนั้นเรียกใช้ดังนี้:

$ python expander.py data/*

zlib.decompressขอบคุณฉันรู้เกี่ยวกับ บางทีฉันอาจจะใช้ฟังก์ชั่นการเดิน ผมไม่แน่ใจว่าถ้าเปลือกจะจัดการจำนวนมากของฉันของไฟล์ที่มีสัญลักษณ์แทน glob :)

ไฟล์ที่สร้างโดยการขยายยังตรวจสอบว่าเป็น "ข้อมูลบีบอัด zlib" สำหรับฉันโดยใช้fileคำสั่งเชลล์? มันเป็นอย่างไร
K. -Michael Aye

ไม่ไม่ทำงานสำหรับฉันแม้จะมีส่วนหัวปลอม
cybernard

3

ตัวอย่างโปรแกรมที่zpipe.c พบโดย Mark Adler ที่นี่ (มาพร้อมกับการกระจายแหล่งที่มาของไลบรารี zlib) มีประโยชน์มากสำหรับสถานการณ์เหล่านี้ด้วยข้อมูลดิบ zlib คอมไพล์ด้วยcc -o zpipe zpipe.c -lzและเพื่อคลายการบีบอัด: zpipe -d < raw.zlib > decompressed. นอกจากนี้ยังสามารถทำการบีบอัดโดยไม่ต้อง-dตั้งค่าสถานะ


2

บน macOS ซึ่งเป็น POSIX ที่สอดคล้องกับ UNIX เต็มรูปแบบ (ได้รับการรับรองอย่างเป็นทางการ!) OpenSSLไม่มีzlibการสนับสนุน แต่zlib-flateอย่างใดและในขณะที่วิธีแก้ปัญหาแรกทำงานเช่นเดียวกับโซลูชั่น Python ทั้งหมดโซลูชันแรกต้องการข้อมูล ZIP ในไฟล์ และโซลูชันอื่น ๆ ทั้งหมดบังคับให้คุณสร้างสคริปต์ Python

ต่อไปนี้เป็นโซลูชันที่ใช้ Perl ซึ่งสามารถใช้เป็นบรรทัดคำสั่งแบบหนึ่งซับได้รับอินพุตผ่านทางท่อ STDIN และใช้งานได้ทันทีด้วย macOS ที่ติดตั้งใหม่:

cat file.compressed | perl -e 'use Compress::Raw::Zlib;my $d=new Compress::Raw::Zlib::Inflate();my $o;undef $/;$d->inflate(<>,$o);print $o;'

การจัดรูปแบบที่ดีกว่าสคริปต์ Perl มีลักษณะดังนี้:

use Compress::Raw::Zlib;
my $decompressor = new Compress::Raw::Zlib::Inflate();
my $output;
undef $/;
$decompressor->inflate(<>, $output);
print $output;

1

คุณสามารถใช้สิ่งนี้เพื่อบีบอัดด้วย zlib:

openssl enc -z -none -e < /file/to/deflate

และนี่คือการยุบ:

openssl enc -z -none -d < /file/to/deflate

4
ให้unknown option '-z'บน Ubuntu 16.04 และOpenSSL 1.0.2g 1 Mar 2016
Tino

2
ข้อผิดพลาดเดียวกันบน Mac
K. -Michael Aye

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.