bash下用sed解析MP3文件名:如何将" - "作为整体分隔符?
MP3文件名提取标题的Bash实现方案
问题需求
需要从MP3文件名中提取标题部分,文件名格式为[曲目编号] - [艺术家名称] - [标题...],分隔符为**" - "(空格-空格)**,且标题内容中可能包含该分隔符。
现有问题
原sed命令错误地将分隔符拆分为单个字符(空格、减号)进行匹配,而非作为完整字符串处理,导致提取结果不符合预期。例如原命令中的[^ - ]和[${SEPARATOR}]都是按字符集匹配,无法识别完整的分隔符。
解决方案
以下提供三种可靠实现方式,优先推荐纯Bash参数扩展的方法,无需依赖外部工具:
方法1:纯Bash参数扩展(高效推荐)
利用Bash的字符串截取功能,两次截断开头的分隔符前内容:
SEPARATOR=" - " filename="07 - Shadowrunner and Syst3m-Glitch - Eastbound Plane Mattaei (Original - Long Mix).mp3" # 第一次截断:去掉第一个分隔符及之前的内容 temp=${filename#*"$SEPARATOR"} # 第二次截断:去掉第二个分隔符及之前的内容,剩余即为标题 title=${temp#*"$SEPARATOR"} echo "$title" # 输出:Eastbound Plane Mattaei (Original - Long Mix).mp3
解释:${var#*"str"}表示从变量var开头删除到第一个匹配str的位置(包含str),两次操作后即可得到标题部分。
方法2:Awk工具(处理复杂场景)
Awk支持指定多字符分隔符,适合需要拆分字段的场景:
SEPARATOR=" - " filename="01 - Skyway - Chillwave - Synthwave - Retrowave Mix.mp3" title=$(echo "$filename" | awk -F "$SEPARATOR" '{ for(i=3; i<=NF; i++) { printf "%s%s", $i, (i<NF ? FS : "\n") } }') echo "$title" # 输出:Chillwave - Synthwave - Retrowave Mix.mp3
解释:用" - "作为分隔符,从第3个字段开始拼接所有后续字段(前两个字段为曲目编号和艺术家),保留标题中原有的分隔符。
方法3:改进Sed命令(需注意正则兼容性)
若坚持使用Sed,需用正则匹配完整分隔符,避免字符集错误:
SEPARATOR=" - " filename="02 - Baldocaster - Astral Dive.mp3" # GNU Sed支持非贪婪匹配,写法更简洁 title=$(echo "$filename" | sed -E "s/^.*?${SEPARATOR}.*?${SEPARATOR}//") # 兼容BSD Sed的写法(无贪婪匹配支持) # title=$(echo "$filename" | sed -E "s/^[^-]*${SEPARATOR}[^-]*${SEPARATOR}//") echo "$title" # 输出:Astral Dive.mp3
注意:部分版本的Sed(如BSD Sed)不支持.*?非贪婪匹配,需使用兼容写法。
测试验证
将所有示例文件名代入上述方法,均可正确提取标题:
- 输入
'01 - Skyway - Chillwave - Synthwave - Retrowave Mix.mp3'→ 输出Chillwave - Synthwave - Retrowave Mix.mp3 - 输入
'05 - Jacket. and Shadowrunner - Deathtouch.mp3'→ 输出Deathtouch.mp3 - 输入
'06 - Night Drive - A Synthwave Mix.mp3'→ 输出A Synthwave Mix.mp3
内容的提问来源于stack exchange,提问作者eyesound
相关产品推荐
相关产品推荐

