通过在某一点截断来重命名一组文件

通过在某一点截断来重命名一组文件

我需要将一堆音乐文件重命名Artist - Title [FREE DL].mp3Artist - Title [FREE DL] [PREMIERE].mp3Artist - 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变量,因为它的值可以在内联中同样很好地扩展。

相关内容