Como criar um arquivo gzip sem a extensão de arquivo .gz?

14

Gostaria de criar um arquivo compactado em gz que retém o nome do arquivo original. Por exemplo, gzipping "example.txt" deve gerar um arquivo gzipped chamado "example.txt" em vez de "example.txt.gz". É possível fazer isso elegantemente com um comando (não executando um subseqüente mv)?

jamieb
fonte
4
Estou um pouco curioso. Por que voce quer isso? Parece uma má ideia.
Bernhard
3
Sim. Você coloca duas linhas inteiras em um script bash e o chama "my-elegant-command". ;)
goldilocks
2
@ Bernhard Faz parte de um processo de criação de integração contínua para um aplicativo Web. Os recursos estáticos (arquivos CSS, JS) precisam ser compactados sem alterar o nome do arquivo. Quando entregue ao navegador, um cabeçalho "codificação de conteúdo: gzip" é incluído para que a extensão seja irrelevante. Mas se o nome do arquivo for alterado, eu tenho que fazer uma pesquisa e substituição nos arquivos HTML de origem.
21313 jamieb
Se isso realmente é um problema para você, você pode definir uma função bash que transmita $ * para o executável gzip e a segunda linha faz o mv para você.
Bratchley
4
@your problema aplicativo web: qualquer servidor decente pode / vai fazer a compressão para você ...
Bananguin

Respostas:

12

Isso não funciona:

# 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>

Esta é uma condição de corrida:

# 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

O problema é que o > example.txt(oudd of=example.txt esse assunto) mata o arquivo antes que o outro processo tenha a chance de lê-lo. Portanto, não há uma solução óbvia, e é por isso que você deve se ater mv.

Existem várias maneiras de trapacear. Você pode abrir o arquivo e desvinculá-lo - o arquivo continuará existindo até você fechá-lo - e criar um novo arquivo com o mesmo nome e gravar os dados compactados nele. No entanto, eu não conheço uma maneira óbvia de coagir o bash a usá-lo, e mesmo se soubesse, minha resposta ainda seria:

Nem faça isso.

Se gzipfalhar por qualquer motivo ou ocorrer algum problema, como você ficar sem espaço enquanto faz o gzip (porque outros processos estão gravando ou o resultado do gzip é maior que a entrada - o que acontece com dados aleatórios - etc.), você acabou de perder o arquivo . Parabéns!

Crie um arquivo separado e mvcom sucesso. Esse é o método mais simples, fácil de entender e mais confiável que você encontrará.

frostschutz
fonte
1
Que tal adicionar por uma questão de integridade:gzip example.txt && mv example.txt.gz example.txt
depquid
2
Não é necessário ler o OP - isso é deselegante .
Goldilocks
@goldilocks "Crie um arquivo separado e mvcom sucesso." pode ser feito mais elegante? Eu estava apenas tentando propor que a resposta de frostschutz fosse aumentada com um exemplo específico. Se mvpuder ser usado com mais elegância do que eu pensava, por favor, dê um exemplo.
depquid 21/03
Sua sugestão é a abordagem simples, elegante e óbvia, mas se funciona depende de muitas variáveis, por exemplo, o que você faz se já existe um exemplo.txt.gz? Além disso, sem nenhuma extensão para trabalhar, você precisa impedir que os arquivos já sejam compactados de alguma forma. Essa é uma nova lata de vermes, mas isso não fazia parte da questão.
precisa saber é o seguinte
10

Eu tive o mesmo problema, como parte de uma implantação de IC no AWS S3.

Isto é o que eu fiz para compactar recursivamente um diretório (no local) sem o .gzsufixo:

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

Parece limpo o suficiente para mim. Mas sim, parece que você precisa de um mvem algum lugar.

Se você estiver usando, gruntvocê pode olhar grunt-contrib-compress. Algumas das gruntferramentas especificamente para implantar no S3 também manipularão o gzip.

tobek
fonte
1
deve ser find . -type ...não find.adicionar o espaço por favor :)
Humdinger
2

-S extensão que você deseja

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

resultará em dog.txt_2015_11

quando você descompacta, deve especificar a extensão.

gzip -d _2015_11 dog.txt_2015_11

No unix, use o comando file para determinar que tipo de arquivo você possui, as extensões são enganosas ou estão faltando com freqüência.

user143758
fonte
1

Não acho que criar um arquivo gzip sem extensão seja realmente a coisa certa a se fazer.

IMHo você deve configurar seu servidor web para ler o arquivo .gz. Você provavelmente já possui uma regra como esta:

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

Você só precisa adicionar uma regra reescrevendo o nome do arquivo solicitado para anexar ".gz" (na verdade, você deve verificar se o arquivo existe, assim como verificar se o cliente listou o gzip no cabeçalho Accept-Encoding)

Anjo
fonte
1

Você pode tentar o s3_website para isso.

Não gosto do fato de estar escrito em scala e ruby ​​e que precisa de uma JVM. Também não gosto da suposição que ela faz (especialmente o fato de excluir arquivos extras do bucket), mas deve funcionar se você estiver bem com isso.

Estou planejando escrever uma ferramenta sozinha que não tenha essas limitações, fique atento.

Cristian Măgherușan-Stanciu
fonte
0

Isso não é realmente algo que você deveria fazer, principalmente porque ao transferir esse arquivo para outros sistemas ou pessoas, pode acabar sendo confuso para eles e não encontrá-lo como um arquivo compactado.

Se você não deseja usar nenhum sufixo, o GNU não é bom para você, pois gzip -S ""retornaria a gzip: invalid suffix ''.

No entanto, você sempre pode enviar algo como gzip -S " "(espaço em branco), e será mostrado assim:

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

Posteriormente, se você quiser descompactá-lo, precisará fazer algo como gunzip -c testfile\ (sem especificar o sufixo) ou mesmo com o -fsinalizador.

Sinceramente, acho que adicionar um mvcomando com &&não seria tão problemático para o seu código. Enfim, e como o @frostschutz disse, não é uma boa ideia fazer isso.

AleksanderKseniya
fonte
Isso é necessário se você deseja usar o S3 para veicular arquivos compactados, como para hospedar um site estático. Você pode considerar o seguinte: github.com/laurilehmijoki/s3_website
Cristian Măgherușan-Stanciu