请求协助:将Python正则表达式转换为Bash正则以标准化文件名
Bash流媒体文件名转换方案:正则适配与格式化
需求概述
我正在编写Bash脚本处理家庭网络流媒体文件,需要将现有Python风格正则转换为Bash兼容的写法,实现以下目标:
- 提取文件名中的质量(如720p/1080p)、发行年份(4位数字)、剧集信息(如S01E05/1x05)
- 将文件名统一转为小写,用下划线替代空格
- 目标格式示例:
harry_potter_2001_720p_philosophers_stone.mkv s01e05_fringe_1080p.mkv
工具推荐
Bash环境下推荐组合使用以下工具:
grep -P:支持Perl兼容正则(PCRE),适合精准提取匹配内容sed:高效处理字符串替换、清理tr:快速完成大小写转换、字符替换- Bash内置参数扩展:简化字符串截取、替换操作
Python正则转Bash实现
以下是对应原Python正则的Bash写法:
1. 提取质量(720p/1080p等)
原Python正则:[0-9]{3}[PpIi]{1}|[0-9]{4}[PpIi]{1}
Bash实现(提取并转小写):
quality=$(echo "$filename" | grep -Po '[0-9]{3,4}[PpIi]' | tr 'A-Z' 'a-z')
-P:启用PCRE正则-o:仅输出匹配的部分tr 'A-Z' 'a-z':统一转为小写
2. 提取发行年份(4位数字)
原Python逻辑:先匹配4位数字+非字母,再提取数字
Bash简化实现(直接匹配符合条件的年份):
year=$(echo "$filename" | grep -Po '[0-9]{4}(?=[^A-Za-z])')
(?=[^A-Za-z]):正向预查,确保4位数字后紧跟非字母字符,避免误匹配剧集编号(如S2023E01中的2023)
3. 提取剧集信息(S01E05/1x05等)
原Python正则:[Ss]{1}[0-9]{2}[Ee]{1}[0-9]{2}|[0-9]{1}[x]{1}[0-9]{2}
Bash实现(忽略大小写并转小写):
episode=$(echo "$filename" | grep -Po 'S\d{2}E\d{2}|[0-9]x\d{2}' -i | tr 'A-Z' 'a-z')
-i:忽略大小写,匹配S/s、E/e、X/x\d:等价于[0-9],PCRE语法更简洁
完整文件名格式化脚本示例
以下是整合所有逻辑的脚本片段,可直接嵌入你的Bash脚本:
# 示例输入文件名 input_filename="Harry Potter and the Philosopher's Stone 2001 720p.mkv" # input_filename="Fringe S01E05 1080p.mkv" # 1. 基础清理:转小写+空格替换为下划线 clean_name=$(echo "$input_filename" | tr 'A-Z' 'a-z' | sed 's/ /_/g') # 2. 提取关键信息 quality=$(echo "$input_filename" | grep -Po '[0-9]{3,4}[PpIi]' | tr 'A-Z' 'a-z') year=$(echo "$input_filename" | grep -Po '[0-9]{4}(?=[^A-Za-z])') episode=$(echo "$input_filename" | grep -Po 'S\d{2}E\d{2}|[0-9]x\d{2}' -i | tr 'A-Z' 'a-z') # 3. 生成目标文件名 ext="${input_filename##*.}" # 提取文件扩展名 if [ -n "$episode" ]; then # 剧集格式:剧集编号_名称_质量.扩展名 # 移除原文件名中的剧集标识,清理多余下划线 base=$(echo "$clean_name" | sed "s/$episode//g" | sed 's/__/_/g' | sed 's/_\./\./') target="${episode}_${base%.*}_${quality}.${ext}" else # 电影格式:名称_年份_质量.扩展名 # 移除原文件名中的年份和质量,清理多余下划线 base=$(echo "$clean_name" | sed "s/${year}//g" | sed "s/${quality}//g" | sed 's/__/_/g' | sed 's/_\./\./') target="${base%.*}_${year}_${quality}.${ext}" fi # 输出结果 echo "原文件名:$input_filename" echo "目标文件名:$target"
注意事项
- 如果文件名包含特殊字符(如
()、[]),建议在变量引用时加双引号(如"$filename")避免解析错误 - 可结合
find命令批量处理目录下所有流媒体文件,例如:find /path/to/media -type f \( -name "*.mkv" -o -name "*.mp4" \) | while read -r file; do # 这里嵌入上述格式化逻辑,处理$file done
内容的提问来源于stack exchange,提问作者John Doe
相关产品推荐
相关产品推荐

