Bash脚本:如何提取含多个点的文件格式并优化文件分拣器?
文件分拣器的格式提取问题与代码优化建议
一、解决多分隔点文件名的格式提取问题
原代码用cut -f 2 -d '.'只能提取第一个点后的内容,无法处理file.name.pdf这类含多个点的文件名。正确做法是提取最后一个点之后的后缀,直接用Bash原生参数展开即可,无需调用外部命令:
format=${file##*.}
${var##pattern}的作用是从变量开头删除最长匹配pattern的内容,这里*.匹配最后一个点及之前的所有字符,剩余部分就是文件后缀。- 无后缀文件(如
README)或隐藏文件(如.bashrc)会直接返回文件名本身,后续case分支会匹配到默认项,符合预期。
二、代码优化建议
- 补全未定义变量:原代码使用了
$music但未定义,需添加音乐目录的路径定义。 - 变量引用加双引号:所有涉及文件路径的变量必须用双引号包裹,避免文件名含空格、特殊字符时出错。
- 路径拼接更安全:用
"$downloads/$file"替代$downloads$file,防止因目录末尾无/导致路径拼接错误。 - 移除无用sleep:
inotifywait是实时触发,sleep 1s完全多余,只会延迟文件处理。 - 确保目标目录存在:用
mkdir -p提前创建目标目录,避免因目录不存在导致移动失败。 - 修正拼写错误:将
recongnized改为recognized。 - 过滤临时文件:跳过浏览器下载时生成的
.part临时文件和隐藏文件,减少误触发。
优化后的完整代码
#!/bin/bash # 目录路径定义(遵循Bash脚本大写变量惯例) PICTURES="$HOME/media/pictures/" VIDEOS="$HOME/media/videos/" DOCUMENTS="$HOME/Documents/" MUSIC="$HOME/media/music/" DOWNLOADS="$HOME/Downloads/" # 提前创建目标目录(不存在则创建) mkdir -p "$PICTURES" "$VIDEOS" "$DOCUMENTS" "$MUSIC" inotifywait -m "$DOWNLOADS" -e moved_to | while read -r dir action file; do # 跳过隐藏文件和下载临时文件 [[ "$file" == .* || "$file" == *.part ]] && continue # 提取后缀并转小写,统一匹配规则 format="${file##*.}" format=$(echo "$format" | tr '[:upper:]' '[:lower:]') notify-send "文件已检测!" "下载目录新增文件:$file" case "$format" in jpg|png|jpeg) mv -n "$DOWNLOADS/$file" "$PICTURES" notify-send "文件已移动" "'$file' 已移至图片目录" ;; mp3|wav|flac) mv -n "$DOWNLOADS/$file" "$MUSIC" notify-send "文件已移动" "'$file' 已移至音乐目录" ;; mp4|ogg|mkv) mv -n "$DOWNLOADS/$file" "$VIDEOS" notify-send "文件已移动" "'$file' 已移至视频目录" ;; doc|docx|pdf|html|txt) mv -n "$DOWNLOADS/$file" "$DOCUMENTS" notify-send "文件已移动" "'$file' 已移至文档目录" ;; *) notify-send "格式未识别" "'$file' 保留在下载目录" ;; esac done
额外优化说明
read添加-r参数,防止文件名中的反斜杠被转义。- 后缀转小写,避免因
.JPG、.PDF等大小写差异导致匹配失败。 mv添加-n参数,防止覆盖目标目录中已存在的同名文件。
内容的提问来源于stack exchange,提问作者Bruheem
相关产品推荐
相关产品推荐

