Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm trying to create a shell script which receive as first parameter of a path to a folder which I would like to compress all files using gzip without overwrite the .gz files that already exist in this folder.

I don't know for which reason this script is not working properly:


for f in *.*; do
  if [ ! -f "$f.gz" ]; then
    echo "Compressing $f file..";
    gzip $f
    echo "Not overwriting $f.gz";

Sometime it gets confused about if the file is a .gz file and don't compress it.

share|improve this question
Small note: quotation is needed to handle spaces and other special characters in filenames, i.e. cd "$FOLDER" and gzip "$f". – Daniel Andersson Feb 20 '13 at 13:10
up vote 2 down vote accepted

Your criteria are wrong. *.* will return all files with extensions. For example, foo.gz. Now you're checking the following, in pseudocode:

if [ foo.gz.gz does not exist ]
    compress foo.gz to foo.gz.gz
    don't overwrite foo.gz.gz

So, your test command will always branch off to compressing something because the test will always evaluate to true. In the end you'll always overwrite your files, because "$f.gz" will expand to foo.gz.gz.

If your real requirement is to match everything but .gz files in your current directory, Bash has easier ways to do that, e.g. by using the extglob option and negation.


shopt -s extglob

cd "$FOLDER"
for f in !(*.gz); do
  if [[ ! -d "$f" ]]; then
    gzip "$f"

You can include a check for whether the file name returned isn't actually a directory—unless you want to compress directories as well.

But actually, Linux gives you better tools to find files matching certain criteria. To (recursively) find all files that don't end with .gz and compress them:

find /some/where -type f ! -iname '*.gz' -exec gzip '{}' \;

If you don't want recursion:

find /some/where -type f -maxdepth 1 ! -iname '*.gz' -exec gzip '{}' \;
share|improve this answer
Actually, gzip just exits with gzip: test.gz already has .gz suffix -- unchanged and status 0 when run on files that already has the extension. But it is unnecessary matching nevertheless, as you say, and the [ ! -f ] test in the question would also do unexpected things if there was a subdirectory with a dot in it that matched the glob. (You have left an echo statement in the first find example.) – Daniel Andersson Feb 20 '13 at 13:15
Thanks, fixed that. – slhck Feb 20 '13 at 13:23
@slhck, thanks for your help! – Valter Silva Feb 20 '13 at 14:45

You must log in to answer this question.

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