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)?


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á.


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.


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.


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)


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.


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.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.