Shell Script to GZIP files without overwrite .gz files

13,425

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

#!/bin/bash
FOLDER=$1

shopt -s extglob

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

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:
13,425

Related videos on Youtube

Valter Silva
Author by

Valter Silva

Updated on September 18, 2022

Comments

  • Valter Silva
    Valter Silva almost 2 years

    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:

    #!/bin/bash
    FOLDER=$1
    
    cd $FOLDER
    for f in *.*; do
      if [ ! -f "$f.gz" ]; then
        echo "Compressing $f file..";
        gzip $f
      else
        echo "Not overwriting $f.gz";
      fi
    done
    

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

    • Daniel Andersson
      Daniel Andersson over 11 years
      Small note: quotation is needed to handle spaces and other special characters in filenames, i.e. cd "$FOLDER" and gzip "$f".
  • Daniel Andersson
    Daniel Andersson over 11 years
    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.)