Domanda

Sto cercando una riga di comando wrapper per l'algoritmo di sgonfiarsi.

Ho un file (blob Git) che viene compresso utilizzando DEFLATE, e voglio decomprimerlo. Il comando gzip non sembra avere la possibilità di utilizzare direttamente l'algoritmo DEFLATE, piuttosto che il formato gzip.

Idealmente Sto cercando uno strumento standard Unix / Linux che può fare questo.

modifica: Questa è l'uscita ottengo quando si cerca di usare gzip per il mio problema:

$ cat .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 | gunzip

gzip: stdin: not in gzip format
È stato utile?

Soluzione

UPDATE: Mark Adler ha notato che le macchie git non sono flussi sgonfiare prime, ma i flussi zlib. Questi possono essere decompressi dallo strumento pigz, che viene pre-confezionato in diverse distribuzioni Linux:

$ cat foo.txt 
file foo.txt!

$ git ls-files -s foo.txt
100644 7a79fc625cac65001fb127f468847ab93b5f8b19 0   foo.txt

$ pigz -d < .git/objects/7a/79fc625cac65001fb127f468847ab93b5f8b19 
blob 14file foo.txt!

La mia risposta originale, conservato per ragioni storiche:

Se ho capito il suggerimento nel Wikipedia articolo citato da Marc van Kempen, è possono utilizzare puff.c da zlib direttamente.

Questo è un piccolo esempio:

#include <assert.h>
#include <string.h>
#include "puff.h"

int main( int argc, char **argv ) {
    unsigned char dest[ 5 ];
    unsigned long destlen = 4;
    const unsigned char *source = "\x4B\x2C\x4E\x49\x03\x00";
    unsigned long sourcelen = 6;    
    assert( puff( dest, &destlen, source, &sourcelen ) == 0 );
    dest[ 4 ] = '\0';
    assert( strcmp( dest, "asdf" ) == 0 );
}

Altri suggerimenti

Qualcosa come il seguente sarà stampare il contenuto grezzo, tra cui il "$ tipo $ lunghezza \ 0" intestazione:

perl -MCompress::Zlib -e 'undef $/; print uncompress(<>)' \
     < .git/objects/27/de0a1dd5a89a94990618632967a1c86a82d577

Si può fare questo con lo strumento da riga di comando OpenSSL:

openssl zlib -d < $IN > $OUT

Purtroppo, almeno su Ubuntu, il sottocomando zlib è disattivata nella configurazione di generazione di default (--no-zlib --no-zlib-dynamic), quindi si avrebbe bisogno di compilare openssl dal sorgente per usarlo. Ma è abilitato di default su Arch, per esempio.

Edit: Sembra che il comando zlib non è più supportato su Arch sia. Questa risposta potrebbe non essere più utili: (

divinatorio one-liner:

$> python -c "import zlib,sys;print \
           repr(zlib.decompress(sys.stdin.read()))" < $IN

È possibile utilizzare zlib-flate, in questo modo:

cat .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 \
    | zlib-flate -uncompress; echo

E 'lì per impostazione predefinita sulla mia macchina, ma è parte di qpdf - tools for and transforming and inspecting PDF files se è necessario installarlo.

Ho spuntato un echo sulla fine del comando, come è più facile da leggere l'output in quel modo.

Prova il seguente comando:

printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" | cat - .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 | gunzip

Non sono necessari strumenti esterni.

Fonte: Come i dati zlib decomprimere in UNIX? a unix SE

Ecco un rubino one-liner (cd .git / primo e identificare il percorso a qualsiasi oggetto):

ruby -rzlib -e 'print Zlib::Inflate.new.inflate(STDIN.read)' < ./74/c757240ec596063af8cd273ebd9f67073e1208

Mi sono stancato di non avere una buona soluzione per questo, così ho messo qualcosa sul NPM:

https://github.com/jezell/zlibber

Ora può solo tubo a gonfiare / sgonfiare il comando.

Ecco un esempio di rottura aprire un commit oggetto in Python:

$ git show
commit 0972d7651ff85bedf464fba868c2ef434543916a
# all the junk in my commit...
$ python
>>> import zlib
>>> file = open(".git/objects/09/72d7651ff85bedf464fba868c2ef434543916a")
>>> data = file.read()
>>> print data
# binary garbage
>>> unzipped_data = zlib.decompress(data)
>>> print unzipped_data
# all the junk in my commit!

Quello che vedrete non v'è quasi identica a quella di uscita di '-p cat-file di git [hash]', salvo che il comando non stampa l'intestazione ( 'commettere' seguito dalla dimensione del contenuto e un null byte).

appare come Mark Adler noi ha in mente e hanno scritto un esempio di come fare questo con: http: //www.zlib.net/zpipe.c

Si compila con nient'altro che gcc -lz e gli header zlib installate. Ho copiato il binario risultante alla mia /usr/local/bin/zpipe mentre si lavora con roba git.

oggetti git vengono compressi zlib anziché gzip, quindi o utilizzando zlib per decomprimere, o comando git, cioè git cat-file -p <SHA1>, per stampare il contenuto.

// save this as deflate.go

package main

import (
    "compress/zlib"
    "io"
    "os"
    "flag"
)

var infile = flag.String("f", "", "infile")

func main() {
    flag.Parse()
    file, _ := os.Open(*infile)

    r, err := zlib.NewReader(file)
    if err != nil {
        panic(err)
    }
    io.Copy(os.Stdout, r)

    r.Close()
}

$ go build deflate.go
$ ./deflate -f .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7

http://en.wikipedia.org/wiki/DEFLATE#Encoder_implementations

Si elenca una serie di implementazioni software, tra gzip, in modo che dovrebbe funzionare. Hai provato solo in esecuzione gzip sul file? Ha non riconosce il formato automaticamente?

Come fai a sapere che è compresso utilizzando DEFLATE? Quale strumento è stato utilizzato per comprimere il file?

Perché non basta usare gli strumenti di Git per accedere ai dati? Questo dovrebbe essere in grado di leggere qualsiasi oggetto git:

git show --pretty=raw <object SHA-1>

Ho trovato questa domanda cerca di un work-around con un bug con l'utilità -text nella nuova versione del client hadoop dfs ho appena installato. L'utilità -text funziona come cat, a meno che l'essere di lettura file è compresso, si decomprime in modo trasparente e in uscita il solo testo (da qui il nome).

Le risposte già postato erano sicuramente utile, ma alcuni di loro hanno un problema quando si tratta di quantità Hadoop dimensioni di dati -. Leggono tutto in memoria prima di decompressione

Così, qui sono le mie variazioni sui Perl e Python risposte sopra che non hanno questa limitazione:

Python:

hadoop fs -cat /path/to/example.deflate |
  python -c 'import zlib,sys;map(lambda b:sys.stdout.write(zlib.decompress(b)),iter(lambda:sys.stdin.read(4096),""))'

Perl:

hadoop fs -cat /path/to/example.deflate |
  perl -MCompress::Zlib -e 'print uncompress($buf) while sysread(STDIN,$buf,4096)'

Si noti l'uso del sub-comando di -cat, invece di -text. Questo è così che il mio lavoro-around non si rompe dopo che hanno risolto il bug. Ci scusiamo per la leggibilità della versione di Python.

oggetti git sono flussi zlib (non sgonfiare crudo). pigz sarà decomprimere quelli con l'opzione -dz.

pigz in grado di farlo:

apt-get install pigz
unpigz -c .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7
const zlib = require("zlib");
const adler32 = require("adler32");
const data = "hello world~!";
const chksum = adler32.sum(new Buffer(data)).toString(16);
console.log("789c",zlib.deflateRawSync(data).toString("hex"),chksum);
// or
console.log(zlib.deflateSync(data).toString("hex"));

Per aggiungere alla collezione, qui ci sono perl one-liners per sgonfiare / gonfiare / sgonfiare raw / gonfiare crudo.

Deflate

perl -MIO::Compress::Deflate -e 'undef $/; my ($in, $out) = (<>, undef); IO::Compress::Deflate::deflate(\$in, \$out); print $out;'

gonfiare

perl -MIO::Uncompress::Inflate -e 'undef $/; my ($in, $out) = (<>, undef); IO::Uncompress::Inflate::inflate(\$in, \$out); print $out;'

Raw deflate

perl -MIO::Compress::RawDeflate -e 'undef $/; my ($in, $out) = (<>, undef); IO::Compress::RawDeflate::rawdeflate(\$in, \$out); print $out;'

Raw gonfiare

perl -MIO::Uncompress::RawInflate -e 'undef $/; my ($in, $out) = (<>, undef); IO::Uncompress::RawInflate::rawinflate(\$in, \$out); print $out;'
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top