27

I'm writing a script in which I'm gzipping files.

There's a possibility that I might zip a file, create a file of the same name, and try to gzip this as well, e.g.

$ ls -l archive/
total 4
-rw-r--r-- 1 xyzzy xyzzy  0 Apr 16 11:29 foo
-rw-r--r-- 1 xyzzy xyzzy 24 Apr 16 11:29 foo.gz

$ gzip archive/foo
gzip: archive/foo.gz already exists; do you wish to overwrite (y or n)? n   
    not overwritten

By using gzip --force, I can force gzip to overwrite foo.gz, but in this case, I think that there's a good chance that I might lose data if I overwrite foo.gz. There doesn't seem to be a command line switch to force gzip to leave .gz files alone... a non-interactive version of pressing 'n' at the prompt.

I tried gzip --noforce and gzip --no-force, hoping that these might follow the GNU options standard, but neither of these worked.

Is there a straight forward work-around for this?

Edit:

It turns out that this is one of the times that it pays to read the info page rather than the man page.

From the info page:

`--force'
`-f'
     Force compression or decompression even if the file has multiple
     links or the corresponding file already exists, or if the
     compressed data is read from or written to a terminal.  If the
     input data is not in a format recognized by `gzip', and if the
     option `--stdout' is also given, copy the input data without
     change to the standard output: let `zcat' behave as `cat'.  If
     `-f' is not given, and when not running in the background, `gzip'
     prompts to verify whether an existing file should be overwritten.

The man page was missing the text and when not running in the background

When running in the background, gzip will not prompt, and will not overwrite unless the -f option is invoked.

2
  • 4
    I'm not sure how gzip checks for being backgrounded, but adding '&' in bash on the system I'm working on doesn't do it. Being on the other side of a pipe seems to work, though, so instead of: find ./ ! -name "*gz" -exec gzip {} \; & this works: find ./ ! -name "*gz" -print0 | xargs -0 -n 1 -t gzip gzip reports: gzip: ./2012-July.txt.gz already exists; not overwritten Jun 1, 2015 at 18:23
  • 1
    @BillMcGonigle Your comment should be THE answer!
    – Rockallite
    Nov 23, 2017 at 8:58

3 Answers 3

13

It has dawned on me that the best way to avoid the undesired effect is to not ask the program to perform the undesired effect. That is, simply don't tell it to compress a file if the file is already present in compressed form.

e.g:

if [ ! -f "$file.gz" ]; then 
    gzip "$file"; 
else 
    echo "skipping $file"
fi

or shorter (run true if there is a file.gz, compress file otherwise)

[ -f "$file.gz" ] && echo "skipping $file" || gzip "$file"    
6
  • Unfortunately, this is being run as a system command inside a perl script (long story about why we're not using something like IO::Compress::Gzip, trust me, I've thought about it). The compression command itself is stored in a configuration file. Your latter command looks close to what I need, but I think that I've found something that will fit my needs just a little bit better. I'm going to accept your answer, because it's a better general solution than mine, but see below for what I'm actually going to use. Apr 16, 2013 at 16:30
  • You can poke a file in Perl... Apr 16, 2013 at 17:00
  • 1
    I'm not clear what you mean by poke a file. Apr 16, 2013 at 17:09
  • Lack of association/image use in everyday communications in American English surprises me every time :) Let me try and explain. Conjure up an image of a child poking a dead crow with a stick to see if it's alive or what not. Poking is used to probe for attributes here. Similarly, poking a file would mean to check something about it, such as if it is at all present. At any rate, I feel the act of poking should at the very least mean "attain contact with an exterior object", and that is enough to say "get some information about a file" with an image, instead of spelling it out. Apr 16, 2013 at 22:55
  • "poke" is often hacker slang for setting a memory location. See: en.wikipedia.org/wiki/PEEK_and_POKE#Generic_usage_of_.22POKE.22 Jun 1, 2015 at 18:30
20

The closest thing that I could find to a single command is the following:

yes n | gzip archive/foo

The yes command prints y followed by a linefeed to stdout until it receives a signal. If it has an argument, it will print that instead of y. In this case, it prints n until gzip exits, thus closing the pipe.

This is the equivalent of entering n repeatedly on the keyboard; this will automatically answer the question gzip: archive/foo.gz already exists; do you wish to overwrite (y or n)?

I general, I think that it's better not to try to compress the files if the corresponding gzipped file exists; my solution is noisier, but it fits my particular needs for a drop-in replacement for the gzip command, sitting in a configuration file.

1
  • 1
    another annoyance with this is that gzip exits 2
    – Zombo
    Aug 12, 2018 at 4:11
0

Try:

gzip -d -r ./folder && gzip -r ./folder
1
  • 1
    Any sort of explantation of why this command helps would be welcome.
    – Destroy666
    Aug 22, 2023 at 17:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .