2009-07-25 6 views
35

Desidero emulare la funzionalità di gzcat | coda -n.Come posso bloccare un file zippato senza leggerne l'intero contenuto?

Questo sarebbe utile per le volte in cui ci sono file enormi (di pochi GB o così). Posso seguire le ultime righe di un file di questo tipo senza leggerlo dall'inizio? Dubito che ciò non sarà possibile poiché credo che per gzip, la codifica dipenda da tutto il testo precedente.

Ma comunque mi piacerebbe sapere se qualcuno ha provato a fare qualcosa di simile - forse indagando su un algoritmo di compressione che potrebbe fornire una tale funzionalità.

+0

gzip non è testuale, ma binario. Quindi non ci sono "linee" come nei dati testuali che "coda" possa restituire. – Gumbo

+0

Si potrebbe voler controllare [una domanda simile su SO] (http://stackoverflow.com/questions/14225751/random-access-to-gzipped-files), [le domande frequenti su zlib] (http://zlib.net /zlib_faq.html#faq28) e [examples/zran.c] (https://github.com/madler/zlib/blob/master/examples/zran.c) nel [zlib] (http: // zlib. rete) distribuzione. –

risposta

36

No, non è possibile. Lo zipping algorithm funziona sugli stream e adatta le sue codifiche interne a ciò che il flusso contiene per ottenere il suo elevato rapporto di compressione.

Senza sapere quale sia il contenuto del flusso prima di un certo punto, è impossibile sapere come procedere per decomprimere da quel momento in poi.

Qualsiasi algoritmo che consente di decomprimere parti arbitrarie di esso richiederà più passaggi sui dati per comprimerlo.

+6

Questo è solo parzialmente vero, a seconda di come è stato costruito il file. i file gzip possono contenere più stream, con un ultimo completamente indipendente da quelli precedenti. Puoi semplicemente concatenare i file gzip e avere comunque un file gzip valido. Non conosco i dettagli, ma presumo che sia possibile trovare la posizione dell'ultimo reset del flusso, supponendo che qualsiasi cosa abbia scritto lo stream ricomincia molto spesso. – mc0e

3

Se si ha il controllo su ciò che viene inserito nel file, se è simile a un file ZIP, è possibile archiviare blocchi di dimensioni predeterminate con nomi di file in ordine numerico crescente e quindi decomprimere solo l'ultimo blocco/file.

+3

Questo suona come un buon compromesso. Tuttavia, l'OP dovrebbe essere consapevole che ciò ridurrà il rapporto di compressione. Se il test mostra che il cambio di rapporto è accettabile, questa è una grande idea. –

+1

In realtà è possibile ottenere ciò reimpostando il dizionario di compressione parzialmente attraverso un file, eliminando così la necessità di dividere il file stesso in blocchi. –

7

BGZF è utilizzato per creare file BAM compressi indice gzip creati da Samtools. Questi sono accessibili in modo casuale.

http://samtools.sourceforge.net/

+1

Esattamente. Tuttavia, non è solo per samtools o per BAM! Credo che funzionerà per tutti i dati delimitati dalla linea. –

+1

I file BGZF consentono l'accesso a offset di byte casuali all'interno di gzips appositamente costruiti limitando prima la dimensione del blocco e quindi per ciascun blocco che memorizza la lunghezza in un'intestazione BC (ignorata da gzip) per consentire l'accesso casuale senza decompressione. Strumenti come BAM memorizzano gli offset memorizzando l'offset dell'inizio del blocco e anche l'offset all'interno del blocco. Per ottenere l'indicizzazione orientata alla linea è necessario qualcosa come un file bai o un file di tablatura (anche se questi sono specifici per il formato e il genoma) per mappare dalla linea desiderata per compensare. –

1

Se si tratta di un'opzione, quindi bzip2 potrebbe essere un algoritmo di compressione meglio utilizzare per questo scopo.

Bzip2 utilizza uno schema di compressione a blocchi. In quanto tale, se prendi un pezzo della fine del tuo file che sei sicuro sia abbastanza grande da contenere tutto l'ultimo blocco, puoi recuperarlo con bzip2recover.

La dimensione del blocco è selezionabile al momento della scrittura del file. Questo è ciò che accade quando si imposta -1 (o --fast) a -9 (o - best) come opzioni di compressione, che corrispondono a blocchi di dimensioni da 100k a 900k. Il valore predefinito è 900k.

Gli strumenti della riga di comando bzip2 non ti danno un modo simpatico di farlo con una pipeline, ma dato che bzip2 non è orientato al flusso, forse non è sorprendente.