web-dev-qa-db-ja.com

.gzファイルを上書きせずにGZIPファイルにシェルスクリプト

このフォルダにすでに存在する.gzファイルを上書きせずにgzipを使用してすべてのファイルを圧縮したいフォルダへのパスの最初のパラメータとして受け取るシェルスクリプトを作成しようとしています。 。

このスクリプトが正しく機能していない理由はわかりません。

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

ファイルが.gzファイルであり、圧縮しないかどうかについて混乱することがあります。

2
Valter Silva

あなたの基準は間違っています。 *.*は、拡張子が付いたすべてのファイルを返します。たとえば、foo.gzです。今、あなたは擬似コードで以下をチェックしています:

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

したがって、テストは常にtrueと評価されるため、テストコマンドは常に何かを圧縮するように分岐します。 "$f.gz"foo.gz.gzに展開されるため、最終的には常にファイルを上書きします。


実際の要件が現在のディレクトリ内の.gzファイル以外のすべてに一致することである場合、Bashにはそれを行う簡単な方法があります。 extglobオプションと否定を使用します。

#!/bin/bash
FOLDER=$1

shopt -s extglob

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

ディレクトリも圧縮する場合を除いて、返されるファイル名が実際にはディレクトリではないかどうかのチェックを含めることができます。


しかし実際には、Linuxは、特定の基準に一致するファイルを見つけるためのより優れたツールを提供します。 .gzで終わらないすべてのファイルを(再帰的に)見つけて圧縮するには:

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

再帰が必要ない場合:

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