如何使用 find 和 mv 批量更改多个文件名

如何使用 find 和 mv 批量更改多个文件名

我在许多目录中都有很多拼写错误的文件。

它们拼写正确Localisation.json,我想把它们改成Localization.json

我尝试了这个,但是没有用:

find -type f -name Localis* | xargs mv Localization.json

答案1

注意

第一的find -type f -name Localis* | xargs mv Localization.json永远不会起作用...您需要类似的东西xargs -I {} mv {} Localization.json或设置xargs选项-n 1

第二mv在这里不是正确的选择,因为它会导致所有名为 eg Localisation.json(的文件或任何文件find匹配并输出)在当前工作目录的所有子目录中移动到当前工作目录并重命名为Localization.json每次覆盖此文件...例如find可能会输出类似的内容./subdirectory/Localisation.json,并且会mv像这样翻译:

mv ./subdirectory/Localisation.json Localization.json

将目标目录更改为当前工作目录...您肯定不希望这样。

所以, ...

建议

您可以将find的输出格式化为 NULL 分隔符(尽量避免破坏包含空格的文件名)-print0然后将其通过管道传输到xargs -0如下rename

find -type f -name "Localisation.json" -print0 | xargs -0 rename -n 's/Localisation\.json$/Localization.json/'

或者,甚至更好,而且相对高效...你可以像这样使用自己find的:-execrename

find -type f -name "Localisation.json" -exec rename -n 's/Localisation\.json$/Localization.json/' {} \+

引用论点很重要,-name例如-name "Localis*"

请注意, 部分中的所有内容都CurrentNamerename视为's/CurrentName/NewName/'正则表达式...因此,转义的点\.与文字匹配.,而与$行尾匹配,以排除目录被重命名,以防您有一个具有相同文件名的父目录,例如Localisation.json/Localisation.jsonrename这也可以通过选项实现--nopath

rename的选项-n仅模拟重命名...当对输出满意时将其删除,以进行实际重命名。

解决方法

您可以find使用-execdir从包含匹配文件的子目录中运行指定的命令)mv如下所示:

find -type f -name "Localisation.json" -execdir echo mv -n -- {} Localization.json \;

您还可以在命令字符串中使用find's并利用's 的参数扩展来实现相同的结果,如下所示:-execmvbashbash

find -type f -name "Localisation.json" -exec bash -c 'echo mv -n -- "$1" "${1/%Localisation.json/Localization.json}"' _ {} \;

那就行仅重命名试运行(模拟)...echo当对输出满意时删除以进行实际重命名。

或者在中bash,您可以使用递归 shell 通配符和参数扩展来mv实现相同的结果,如下所示:

shopt -s globstar; for f in **/Localisation.json; do
    # Renaming dry-run(simulation) ... Remove "echo" when satisfied with output to do the actual renaming.
    echo mv -n -- "$f" "${f/%Localisation.json/Localization.json}"
done; shopt -u globstar

答案2

在大多数情况下,重命名文件最简单、最有效的方法是使用命令rename。要在Bash 外壳您需要启用全球星选项:

shopt -s globstar

然后您可以rename按照这样的方式使用该命令:

rename -n --nopath 's/Localisation\.json/Localization.json/' **/*
  • 删除-n禁用空运行模式并执行实际重命名的选项。

您可能需要禁用全球星之后选择采取良好措施:

shopt -u globstar

上述rename命令应该可以直接使用(无需启用其他选项)Zsh 外壳

然而,尽管这种方式效率较低mv必须对每个参数调用as,您可以通过命令字符串find将 的输出传输到 ,如下所示:xargsmvsh

find -type f -name 'Localisation.json' -print0 | xargs -0 -I {} -- sh -c 'echo mv -n -- "$1" $(dirname "$1")/Localization.json' _ {}

echo仅用于试运行。echo对输出满意后删除,以进行实际重命名。

相关内容