Come creare un file gzip senza estensione .gz?


14

Vorrei creare un file gzip che conserva il nome del file originale. Ad esempio gzipping "esempio.txt" dovrebbe generare un file gzippato chiamato "esempio.txt" anziché "esempio.txt.gz". È possibile farlo elegantemente con un comando (non eseguendo un successivo mv)?


4
Sono un po 'curioso Perché lo vuoi? Sembra una cattiva idea.
Bernhard

3
Si. Metti 2 righe intere in uno script bash e lo chiami "my-elegant-command". ;)
Riccioli d'oro

2
@Bernhard Fa parte di un processo di integrazione continua per un'app Web. Le risorse statiche (file CSS, JS) devono essere compresse senza modificare il nome del file. Quando viene consegnato al browser, viene inclusa un'intestazione "codifica contenuto: gzip", quindi l'estensione è irrilevante. Ma se il nome del file viene modificato, devo fare una ricerca e sostituzione nei file HTML di origine.
Jamieb

Se questo è davvero un grosso problema per te, potresti definire una funzione bash che passa $ * all'eseguibile gzip e la seconda riga fa il mv per te.
Bratchley,

4
@il tuo problema con l'app web: qualsiasi server web decente può / farà la compressione per te ...
Bananguin

Risposte:


12

Questo non funziona:

# echo Hello World > example.txt
# gzip < example.txt > example.txt # WRONG!
# file example.txt
example.txt: gzip compressed data, from Unix, last modified: Thu Mar 21 19:45:29 2013
# gunzip < example.txt
<empty file>

Questa è una condizione di gara:

# echo Hello World > example.txt
# dd if=example.txt | gzip | dd of=example.txt # still WRONG!
# gunzip < example.txt 
Hello World # may also be empty

Il problema è che il > example.txt (o dd of=example.txtdel resto) uccide il file prima che l'altro processo abbia la possibilità di leggerlo. Quindi non esiste una soluzione ovvia, motivo per cui dovresti attenerti mv.

Esistono diversi modi per barare. Puoi aprire il file, quindi scollegarlo - il file continuerà a esistere fino a quando non lo chiuderai - e quindi creare un nuovo file con lo stesso nome e scrivere i dati compressi con quello. Comunque non conosco un modo ovvio per costringere Bash a usarlo, e anche se lo facessi, la mia risposta sarebbe ancora:

Non farlo nemmeno.

Se gzip fallisce per qualsiasi motivo o si verifica un problema, ad esempio quando si esaurisce lo spazio durante il gzipping (perché altri processi stanno scrivendo, o il risultato gzip è più grande dell'input - che accade per dati casuali - ecc.), Hai appena perso il tuo file . Congratulazioni!

Crea un file separato e mvin caso di successo. Questo è il metodo più semplice, facile da capire e più affidabile che tu abbia mai trovato.


1
Che ne dici di aggiungere per completezza:gzip example.txt && mv example.txt.gz example.txt
depquid

2
Nessun depquid ha letto l'OP - è inelegante .
Riccioli d'oro

@goldilocks "Crea un file separato e mvin caso di successo." può essere reso più elegante? Stavo solo cercando di proporre di aumentare la risposta di frostschutz con un esempio specifico. Se mvpuò essere usato più elegantemente di quanto pensassi, per favore fai un esempio.
depquid

Il tuo suggerimento è l'approccio semplice, elegante, ovvio, ma se funziona dipende da così tante variabili, ad esempio cosa fai se esiste già un esempio.txt.gz? Inoltre, senza alcuna estensione con cui lavorare, è necessario impedire in qualche modo la compressione dei file già compressi con gzip. È una nuova lattina di vermi, ma in realtà non faceva parte della domanda.
frostschutz,

10

Ho avuto lo stesso problema, come parte di una distribuzione CI su AWS S3.

Questo è quello che ho fatto per gzipare ricorsivamente una directory (sul posto) senza il .gzsuffisso:

find . -type f -exec gzip "{}" \; -exec mv "{}.gz" "{}" \;

Sembra abbastanza pulito per me. Ma sì, sembra che tu abbia bisogno mvdi qualcosa da qualche parte.

Se stai usando gruntpuoi guardare grunt-contrib-compress. Alcuni degli gruntstrumenti specifici per la distribuzione su S3 gestiranno anche gzip per te.


1
dovrebbe essere find . -type ...non find.aggiungere lo spazio si prega :)
Humdinger

2

-S estensione che desideri

gzip -S "`_date +%Y_%M' dog.txt 

comporterà dog.txt_2015_11

quando lo decomprimi devi specificare l'estensione.

gzip -d _2015_11 dog.txt_2015_11

In unix usa il comando file per determinare quale tipo di file hai, le estensioni sono fuorvianti o mancano spesso.


1

Non penso che la creazione di un file gzip senza estensione sia davvero la cosa giusta da fare.

Quindi dovresti configurare il tuo server web per leggere il file .gz. Probabilmente hai già una regola come questa:

Path asets/:
  If header Accept-Encoding contains "gzip" and not contains "gzip;q=0":
    Add header Content-Encoding: gzip

Devi solo aggiungere una regola che riscrive il nome del file richiesto per aggiungere ".gz" (in realtà, dovresti verificare che il file esista, proprio come dovresti verificare che il client abbia elencato gzip nella sua intestazione Accept-Encoding)


1

Puoi provare s3_website per questo.

Non mi piace il fatto che sia scritto sia in scala che in ruby ​​e che abbia bisogno di una JVM. Inoltre, non mi piace il presupposto che fa (in particolare il fatto che elimina i file extra dal bucket), ma dovrebbe funzionare se stai bene.

Sto programmando di scrivere uno strumento del genere da solo che non abbia questi limiti, rimanete sintonizzati.


0

Questo non è davvero qualcosa che dovresti fare, principalmente perché quando trasferisci questo file ad altri sistemi o persone, potrebbe finire per essere fonte di confusione per loro e non trovarlo come file compresso.

Se non vuoi usare alcun suffisso, GNU non è adatto a te, poiché gzip -S ""restituirebbe a gzip: invalid suffix ''.

Tuttavia, potresti sempre inviare qualcosa del tipo gzip -S " "(spazio vuoto) e verrà mostrato in questo modo:

$ file testfile\  
testfile: gzip compressed data, was "testfile", from Unix, last modified: Tue Jun  3 XX:XX:XX 2014

Successivamente, se vuoi decomprimerlo, dovrai fare qualcosa del genere gunzip -c testfile\ (senza specificare il suffisso), o anche con la -fbandiera.

Sinceramente penso che l'aggiunta di un mvcomando con &&non renderebbe molto fastidioso il tuo codice. Comunque, e come ha detto @frostschutz, non è una buona idea farlo.


Questo è necessario se si desidera utilizzare S3 per pubblicare file compressi, ad esempio per ospitare un sito Web statico. Potresti considerare questo: github.com/laurilehmijoki/s3_website
Cristian Măgherușan-Stanciu
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.