我需要将一堆音乐文件重命名Artist - Title [FREE DL].mp3
为Artist - Title [FREE DL] [PREMIERE].mp3
Artist - Title.mp3
我有这个,但是它不起作用而且我也不知道为什么。
find . -type f -name "* - * \[*\].mp3" -o -name "* - * \[*\] \[*\].mp3" -execdir bash -c 'for file in "$@"; do new=${file% \[}.mp3; mv -v "$file" "$new"; done' _ {} +
由于不是 Bash 专家,我无法修复它。我知道 find 正在查找文件,但 rename 不起作用,尝试 oto echo 也$new
不起作用。
答案1
有几个错误:-
- 之所以没有出现任何结果,是因为
-o
如果前面的表达式匹配,则不会执行任何其他操作 - 这包括尝试匹配第二个-name
和执行后续的-execdir
;但第一个表达式匹配两种文件名样式,因此无需执行进一步的操作。如果您确实需要匹配两个不同的文件掩码,请使用括号\( -name ... -o -name ... \)
,但在这种情况下,最好直接删除-o
和第二个-name
子句。 - 一旦
-execdir
执行,文件名扩展就会出现两个错误:${file% \[}
从文件名中删除所有尾随的空格和左方括号 - 没有(所有文件名都以 结尾p3
);- 您需要
${file% \[*}
包含文件名的其余部分,但这还不够好,因为单个%
匹配最短可能的字符串,即仅来自最后的空白和左方括号 - 从第一个需要的地方进行匹配${file%% \[*}
,匹配最长的字符串。
因此你需要的是:
find . -type f \( -name "* - * \[*\].mp3" -o -name "* - * \[*\] \[*\].mp3" \) -execdir bash -c 'for file in "$@"; do new=${file%% \[*}.mp3; mv -v "$file" "$new"; done' _ {} +
或者更简单地说:
find . -type f -name "* - * \[*\].mp3" -execdir bash -c 'for file in "$@"; do new=${file%% \[*}.mp3; mv -v "$file" "$new"; done' _ {} +
我已经尽可能地用测试文件检查了这些,并将其放在命令echo
之前mv
,现在它们似乎可以工作了。
但是,使用 '+' 选项构建一串文件名,然后for
再次使用来隔离它们似乎有点奇怪,所以我最后建议:
find . -type f -name "* - * \[*\].mp3" -execdir bash -c 'file="{}"; echo mv -v "$file" "${file%% \[*}.mp3"' \;
我已经删除了该new
变量,因为它的值可以在内联中同样很好地扩展。