Shell 脚本转为 GZIP 文件而不覆盖 .gz 文件

Shell 脚本转为 GZIP 文件而不覆盖 .gz 文件

我正在尝试创建一个 shell 脚本,该脚本接收一个文件夹的路径作为第一个参数,我想使用该文件夹压缩所有文件gzip而不覆盖.gz该文件夹中已存在的文件。

我不知道这个脚本由于什么原因不能正常工作:

#!/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文件并且不压缩它。

答案1

您的条件是错误的。*.*将返回所有带有扩展名的文件。例如,foo.gz。现在您正在用伪代码检查以下内容:

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

因此,你的测试命令将总是因为测试结果总是为真,所以分支到压缩某些东西。最后你会总是覆盖您的文件,因为"$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 '{}' \;

相关内容