简化子字符串替换列表

简化子字符串替换列表

我写了一个播放音乐的脚本。但这些文件的名称很奇怪。

说我有这个文件名字符串

Muzzy__Break_Away__28feat._Priority_One_29__5BMonstercat_EP_Release_5D.mp3

我想实现这个目标

Muzzy Break Away feat Priority One

到目前为止我已经在 bash 中得到了这个。

file="whatever";
file=${file//_/" "};
file=${file//[0123456789ABCDEF][0123456789ABCDEF]/""};  #replaces bytes
file=${file//.extension1/""};
file=${file//.extension2/""};
file=${file//.extensionn/""}; #many more, e.g. .mp3
file=${file//word1/""};
file=${file//word2/""};
file=${file//wordn/""}; #many more, e.g. Monstrcat
file=${file//./""};
echo "$file";

有没有办法以相同的顺序(区分大小写)在 1 个命令中简化此操作?

答案1

你可能会调用 perl:

formatted=$( perl -lpe '
        s/([0-9A-F]{2})/chr hex $1/eg;   # hex to ascii
        s/_+/ /g;                        # underscores to space
        s/\[[^]]*\]//g;                  # remove bracketed text
        s/[^[:alnum:][:blank:]]//g;      # remove non-alphanumeric,non-blank chars
    ' <<<"${file%.*}"
)
echo "$formatted"
Muzzy Break Away feat Priority One

答案2

这些_28看起来像是某些字符的十六进制编码。也许你想要类似的东西(用zsh而不是bash):

$ autoload zmv
$ zmv -n '*.mp3' '${${f//(#b)_([0-9A-F](#c2))/${(#)$((0x$match))}}//_/ }'
mv -- Muzzy__Break_Away__28feat._Priority_One_29__5BMonstercat_EP_Release_5D.mp3 Muzzy\ \ Break\ Away\ \(feat.\ Priority\ One\)\ \[Monstercat\ EP\ Release\].mp3

如果重点是重命名:

Muzzy__Break_Away__28feat._Priority_One_29__5BMonstercat_EP_Release_5D.mp3

Muzzy  Break Away (feat. Priority One) [Monstercat EP Release].mp3

-n如果满意,请删除(用于空运行))。

如果您有文件名$file并且想要更好用于显示的表示,使用:

set -o extendedglob # (that's on by default in zmv)
display=${${${file//(#b)_([0-9A-F](#c2))/${(#)$((0x$match))}}//_/ }:r}
  • (#b)激活反向引用(因此$match[1]在替换中是模式中捕获的第一个字符串)
  • ${(#)var}将 的内容解释$var为数字并扩展到具有相应代码点的字符
  • $var:r$var获取.中文件名的根名(删除扩展名)

答案3

您可能不应该使用 bash 搜索/替换来执行此操作,如果文件具有 ID3 元数据,您应该从那里读取它并将其与您喜欢的模板一起使用。

$ id3v2 -l file.mp3

Title  : Computer Love                   Artist: Zapp                          
Album  : Golden Gems-80s                 Year: 2017, Genre: Pop (13)
Comment:                                 Track: 29
id3v2 tag info for 29-zapp-computer_love-f3b5b5db.mp3:
TRCK (Track number/Position in set): 29/29
TPE1 (Lead performer(s)/Soloist(s)): Zapp
TIT2 (Title/songname/content description): Computer Love
TCON (Content type): Pop (13)
TALB (Album/Movie/Show title): Golden Gems-80s
TYER (Year): 2017

然后您可以使用 awk/sed/cut/grep 等工具将信息保存到这样的变量中,

Artist=$(id3v2 -l file.mp3 | grep "TPE"  | awk -F: '{print $2}')
Title=$( id3v2 -l file.mp3 | grep "TIT2" | awk -F: '{print $2}')

mv file.mp3 "${Artist} - ${Title}.mp3"

但我真的建议使用类似的工具MP3标签/音乐大脑皮卡德为了管理您的音乐文件,它会给您实时预览,并允许您回滚,以防万一您做错了。

答案4

我使用以下sed命令获得了所需的输出:

echo "Muzzy__Break_Away__28feat._Priority_One_29__5BMonstercat_EP_Release_5D.mp3" \
  | sed "s/_[0-9]\{2\}_.*//g" | sed "s/[_0-9\.]/ /g"| sed -r "s/\s+/ /g"  

输出

Muzzy Break Away feat Priority One  

相关内容