我写了一个播放音乐的脚本。但这些文件的名称很奇怪。
说我有这个文件名字符串
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