首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >帮助我改进bash脚本,它可以找到某些文件类型并移动它们。

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

Unix & Linux用户
提问于 2022-10-18 00:00:12
回答 1查看 38关注 0票数 1

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

代码语言:javascript
复制
#!/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,以及如何添加一些基本的错误检查以确保脚本正常运行?

EN

回答 1

Unix & Linux用户

发布于 2022-10-18 01:00:56

下面是对脚本进行改进的尝试。为了更容易地添加任何错误逻辑,删除了大管道。它还使增加理货逻辑变得更容易。另外,由于我们只读取了一次目录而不是三次,所以速度可能略有提高。此外,通过使用shell变量、子字符串删除和case语句(以及不同的file参数),剪切(以及grep和sed)。

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

代码语言:javascript
复制
#!/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
票数 1
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/721380

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档