You need to enable JavaScript to run this app. Debian 环境下实现特定文件名调整规则的批量重命名脚本求助
优惠活动
大模型
产品
解决方案
定价
更多

Debian 环境下实现特定文件名调整规则的批量重命名脚本求助

Shell批量剧集重命名脚本开发问题

场景与目标

开发Shell自动化脚本,对指定目录树内的剧集文件按统一规则批量重命名,适配Kodi媒体刮削工具的剧集识别逻辑,支撑新文件入库时的自动归档流程。

约定重命名规则

  • 规则1:移除文件名中所有S00-S99范围的季数标识,匹配逻辑为s/[sS](0[1-9]|[1-9][0-9])/
  • 规则2:为文件名中独立存在的两位数字补充E前缀,匹配逻辑为识别文本边界内的两位数字/\b([0-9]{2})\b/,替换为E+匹配内容

规则转换示例

三类格式不一致的源文件,统一转换为Kodi可识别的标准格式:

源文件路径片段转换后目标路径片段
[lorem ipsum] dolor sit amet 07 [consetetur][1080p].mkv[lorem ipsum] dolor sit amet E07 [consetetur][1080p].mkv
[lorem ipsum] dolor sit amet S04 07 [consetetur][1080p].mkv[lorem ipsum] dolor sit amet E07 [consetetur][1080p].mkv
[lorem ipsum] dolor sit amet S04 E07 [consetetur][1080p].mkv[lorem ipsum] dolor sit amet E07 [consetetur][1080p].mkv

现有问题脚本与报错

因不熟悉Shell环境下的正则嵌入逻辑,基于旧脚本框架修改后写出的代码如下:

#!/bin/bash

start_dir="//srv/MEDIA2/"
find "$start_dir" -name '*.*' -type f \
  |sort \
  |while read name; do 
     ((i++))
     mv -i "$name" \
#remove season part
       "$(printf 's/[sS](0[1-9]|[1-9][0-9])/ "$(dirname "$name")" $((i)) "$(basename "$name")")"
#prepend E to free standing double digits
       "$(printf 's/\b([0-9]{2})\b/' "$(dirname "$name")" $((i)) "$(basename "$name")")"
    
done

脚本运行时返回如下错误:

//home/user/./rnscript.sh: line 14: s/[sS](0[1-9]|[1-9][0-9])/: No such file or directory
//home/user/./rnscript.sh: line 16: s([0-9]{2}/: No such file or directory

报错根因

  • mv命令需要传入明确的目标文件路径作为第二个参数,脚本直接把正则替换表达式写在printf的格式串位置,没有将正则逻辑作用于实际文件名,导致Shell把正则表达式本身当成待执行的路径,触发“文件不存在”的报错
  • 脚本未衔接两步替换的上下文:移除季数标识的输出,需要作为下一步“给独立两位数字加E前缀”的输入,而不是把两个正则表达式当成两个独立的mv目标参数
  • 原有路径读取逻辑未处理带空格、特殊字符的文件名,遍历过程中会出现路径拆分错误
  • 路径配置存在冗余双斜杠问题

修正后的可用脚本

#!/bin/bash
# 配置待扫描的媒体根目录
start_dir="/srv/MEDIA2/"

# 以空字符为分隔符遍历文件,兼容带特殊字符、空格的文件名
find "$start_dir" -name '*.*' -type f -print0 \
  | sort -z \
  | while IFS= read -r -d '' full_path; do 
     # 拆分文件所属目录、文件名、扩展名
     file_dir=$(dirname "$full_path")
     file_base=$(basename "$full_path")
     file_name="${file_base%.*}"
     file_ext="${file_base##*.}"

     # 第一步:移除所有S/s开头的两位季数标识,同时清理替换后产生的多余空格
     new_name=$(printf '%s' "$file_name" \
       | sed -E 's/[sS](0[1-9]|[1-9][0-9])//g' \
       | sed -E 's/\s+/ /g; s/^ | $//g'
     )
     # 第二步:给独立存在的两位数字添加E前缀,跳过已经带E的集数避免重复匹配
     new_name=$(printf '%s' "$new_name" \
       | sed -E 's/\b([0-9]{2})\b/E\1/g'
     )

     # 拼接完整新文件路径,路径无变化则跳过
     new_full_path="${file_dir}/${new_name}.${file_ext}"
     if [ "$full_path" != "$new_full_path" ]; then
       # 首次试运行时,先将下方mv行替换为echo输出,预览所有重命名结果
       mv -i "$full_path" "$new_full_path"
       echo "已完成重命名: $full_path -> $new_full_path"
     fi
done

上线验证注意事项

  • 首次运行脚本时,建议先临时注释mv命令行,仅通过echo输出预览全目录的重命名结果,确认替换逻辑无偏差后再开启实际重命名操作,避免误改文件
  • 正则已做边界防护,不会误匹配长数字串、扩展名内的数字、已经带E前缀的集数标识

内容的提问来源于stack exchange,提问作者Sc0rax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 05:15:03