Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I would like to create a gzipped file that retains the original file name. For example gzipping "example.txt" should output a gzipped file named "example.txt" rather than "example.txt.gz." Is it possible to do this elegantly with one command (not doing a subsequent mv)?

share|improve this question
3  
I am a bit curious. Why do you want this? It sounds like a bad idea. –  Bernhard Mar 21 '13 at 18:41
1  
Yeah. You put 2 whole lines in a bash script and call it "my-elegant-command". ;) –  TAFKA 'goldilocks' Mar 21 '13 at 18:45
1  
@Bernhard It's part of a continuous integration build process for a web app. Static assets (CSS, JS files) need to be compressed without changing the file name. When delivered to the browser a "content-encoding: gzip" header is included so the extension is irrelevant. But if the filename is changed, I have to do a search-and-replace in the source HTML files. –  jamieb Mar 21 '13 at 18:45
    
If this is really that much of an issue for you, you could define a bash function that passes $* to the gzip executable and the second line does the mv for you. –  Joel Davis Mar 21 '13 at 19:08
2  
@your web app problem: any decent webserver can/will do the compressing for you ... –  Bananguin Mar 21 '13 at 21:36
add comment

1 Answer

This does NOT work:

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

This is a race condition:

# 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

The problem is that the > example.txt (or dd of=example.txt for that matter) kills the file before the other process has the chance to read it. So there is no obvious solution, which is why you should stick to mv.

There are a number of ways you could cheat. You can open the file, then unlink it - the file will continue to exist until you close it - and then create a new file with the same name and write the gzipped data to that. However I do not know an obvious way to coerce bash to use that, and even if I did, my answer would still be:

Don't even do it.

If gzip fails for any reason, or any problem occurs, like you running out of space while gzipping (because other processes are writing, or gzip result is larger than the input - which happens for random data - etc.), you just lost your file. Congratulations!

Create a separate file and mv on success. That's the simplest, easy to understand, and most reliable method you will ever find.

share|improve this answer
1  
How about adding for the sake of completeness: gzip example.txt && mv example.txt.gz example.txt –  depquid Mar 21 '13 at 19:07
2  
No depquid read the OP -- that's inelegant. –  TAFKA 'goldilocks' Mar 21 '13 at 19:08
    
@goldilocks "Create a separate file and mv on success." can be made more elegant? I was just trying to propose that frostschutz's answer be augmented with a specific example. If mv can be used more elegantly than I thought, please give an example. –  depquid Mar 21 '13 at 21:39
    
Your suggestion is the simple, elegant, obvious approach, but whether it works depends on so many variables, e.g. what do you do if there already is a example.txt.gz? Also with no extension to work with, you have to prevent gzipping already gzipped files somehow. That's a whole new can of worms, but that was not really part of the question. –  frostschutz Mar 21 '13 at 21:49
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.