帮助我改进 bash 脚本,以查找某些文件类型并移动它们

帮助我改进 bash 脚本,以查找某些文件类型并移动它们

我编写了一个bash脚本,1)查找某个目录($DIR1)中的所有图像文件并将它们移动到另一个目录($DIR2)然后2)查找同一$DIR1中的所有视频文件并将它们移动到第三个目录($DIR3),最后找到 $DIR1 中的所有剩余文件并将它们移至第四个目录 ($DIR4)。最终结果是脚本结束时 $DIR1 为空。

#!/bin/bash 

if [ "$(ls -A $DIR1)" ]; then
        echo "moving all photo files to processing directory"
        find $DIR1 -name '*' -exec file {} \; | grep -o -P '^.+: \w+ image' | cut -d':' -f1 | xargs -I{} mv --backup=numbered {} $DIR2;
    else
        echo "directory is empty, skipping"
    fi

if [ "$(ls -A $DIR1)" ]; then
    echo "moving all video files to processing directory"
    find $DIR1 -type f -exec file -N -i -- {} + | sed -n 's!: video/[^:]*$!!p' | cut -d':' -f1 | xargs -I{} mv --backup=numbered {} $DIR3;
else
    echo "directory is empty, skipping"
fi

if [ "$(ls -A $DIR1)" ]; then
    echo "moving all remaining files to manual-review directory"
find $DIR1 -type f -print0 | xargs -0 mv --backup=numbered -t $DIR4;
else
    echo "no remaining files to move, skipping"
fi

该脚本似乎按预期工作,我已经定期运行它几个月,结果符合预期。话虽如此,我希望帮助弄清楚如何让它变得更好,特别是 1)如何计算每次移动的文件数量并将其打印到 STDOUT,以及 2)如何添加一些基本的错误检查以确保脚本的行为是否符合预期?

答案1

这是改进脚本的尝试。大型管道被删除,以便更轻松地添加任何错误逻辑。它还可以更轻松地添加计数逻辑。此外,由于我们读取目录一次而不是三次,因此速度可能会略有提高。此外,通过使用 shell 变量子字符串删除和 case 语句(以及不同的参数)来剪切(以及 grep 和 sed)file

至于错误检查,外部 DIR1/2/3/4 变量周围有引号,并测试它们是开头的目录。我使用 Bash FAQ 中的空终止文件名技术(此处:http://mywiki.wooledge.org/BashFAQ/020)。如果发生这种情况,这将允许文件名中包含空格。当然还有更多的极端情况可以添加,比如如果mv失败或file崩溃你想做什么。

#!/bin/bash 

if [[ ! -d "$DIR1" || ! -d "$DIR2" || ! -d "$DIR3" || ! -d "$DIR3" ]]; then
    echo "missing environment variables or variables aren't directories" >&2
    exit 1
fi

num_images=0
num_videos=0
num_misc=0

echo STARTING
while IFS= read -r -d $'\0' file; do
   mime=$( file -b --mime-type "$file" )
   case "${mime%%/*}" in
      image)
         output="$DIR2"
         ((num_images++))
        ;;
      video)
         output="$DIR3"
         ((num_videos++))
        ;;
      *)
         output="$DIR4"
         ((num_misc++))
        ;;
    esac
    mv "$file" "$output"
done < <( find "$DIR1" -type f -print0 )

echo FINISHED: moved $num_images images, $num_videos videos, $num_misc other files

相关内容