You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 14:05:39