Bash带条件mv命令分类移动文件的脚本故障排查
故障原因
所有if [[ -f *.xxx ]]判断不生效是bash语法特性导致的,并非if语句写法的低级错误:
[[ ]]结构中的-f检测符仅支持接收单个文件路径作为入参。当目录下存在多个匹配*.xxx的文件时,通配符*会展开为多个文件名传入判断语句,参数数量不符合-f的要求,判断会直接返回假。- 当目录下没有任何匹配
*.xxx的文件时,bash默认不会展开通配符,会直接把字符串*.xxx作为文件名做存在性检测,这个文件显然不存在,判断同样返回假。 - 原脚本还存在三个额外逻辑问题:
- 压缩包分类中判断的是
*.zx后缀,实际移动的是*.xz文件,判断和操作不匹配 - 最外层判断要求所有分类目录全部存在才会执行移动,只要缺一个目录就走重建分支,且两个分支的移动代码完全重复,冗余度极高
- 未实现未知格式文件移动到Misc目录的逻辑
- 压缩包分类中判断的是
修复方案
不需要提前用if判断某类后缀的文件是否存在,直接开启bash的nullglob选项即可:该选项生效后,通配符没有匹配到任何文件时会直接展开为空,不会把*.xxx这类字面量字符串传给命令;配合mv的-f强制参数,遇到不存在的文件类型直接跳过,完全可以替代冗余的存在性判断,从根源上避免通配符导致的判断失效问题。
修复后的精简可用脚本如下:
#!/bin/bash # 开启nullglob:通配符无匹配时展开为空,避免将*.xxx作为文件名处理 shopt -s nullglob # 自动创建不存在的分类目录,无需重复判断目录是否存在 target_dirs=(Videos Compressed Music Pictures Executables Documents Misc) mkdir -p "${target_dirs[@]}" echo "开始整理下载目录文件..." # 按分类移动对应后缀的文件,2>/dev/null用于屏蔽无匹配文件时的无关报错 mv -f *.7z *.rar *.xz *.zip *.gz *.iso Compressed/ 2>/dev/null mv -f *.mp4 *.mov *.wvm *.mkv Videos/ 2>/dev/null mv -f *.mp3 *.wav *.ogg Music/ 2>/dev/null mv -f *.png *.jpg *.jpeg *.svg *.webp Pictures/ 2>/dev/null mv -f *.doc *.docx *.pdf *.pptx *.ppt *.xls *.xlsx Documents/ 2>/dev/null mv -f *.64 *.deb *.rpm Executables/ 2>/dev/null # 将剩余未匹配分类的普通文件(排除脚本自身)移动到Misc目录 for file in *; do if [[ -f "$file" && "$file" != "${0##*/}" ]]; then mv -f "$file" Misc/ fi done echo "文件整理完成"
脚本优化说明:
- 用
mkdir -p自动按需创建目录,省去了目录存在/不存在两套完全重复的移动代码,维护成本更低- 修正了原脚本中
.zx和.xz后缀的笔误- 补全了原脚本缺失的未知格式文件归类逻辑,同时做了排除判断,避免把正在运行的整理脚本自身移动到Misc目录
- 所有移动操作加了错误输出屏蔽,不会因为某类文件不存在输出无意义的报错信息
内容的提问来源于stack exchange,提问作者Chester232
相关产品推荐
相关产品推荐

