在 Linux 中递归重命名文件(更改扩展名)

在 Linux 中递归重命名文件(更改扩展名)

如何以递归方式重命名目录中的所有文件,将一个文件扩展名更改为另一个文件扩展名,以用于数千个子文件夹中的数千个文件?我看到很多命令几乎可以完成我想要的操作,但并不完全如此。

find . -name "*.andnav" -exec rename .andnav .tile {} \;
syntax error at (eval 1) line 1, near "."

...

rename -nv 's/\.andnav$/\.tile/i' *.andnav
0.png.andnav renamed as 0.png.tile

答案1

弄清楚了

find . -name "*.andnav" -exec rename -v 's/\.andnav$/\.tile/i' {} \;
./0/0.png.andnav renamed as ./0/0.png.tile
./0/1.png.andnav renamed as ./0/1.png.tile
./1/0.png.andnav renamed as ./1/0.png.tile
./1/1.png.andnav renamed as ./1/1.png.tile

当然,实际执行时请删除 -v,否则会浪费时间显示所有文件

答案2

使用 zsh:

autoload zmv
zmv -n '(**/)(*).andnav' '$1$2.tile'

删除-n以实际执行重命名。

答案3

就像是:

find . -name '*.andnav' -exec sh -c 'mv "$0" "${0%.andnav}.tile"' {} \;

解释

上述代码从当前工作目录 ( .) 开始遍历目录树。每当文件名与模式匹配*.andnav(例如foo.andnav)时,就会执行以下命令:

sh -c 'mv "$0" "${0%.andnav}.tile"' foo.andnav

$0在哪里,foo.andnav并用以下方式${0%.andnav}.tile替换后缀:.andnav.tile

mv foo.andnav foo.tile

答案4

find -execdir rename

https://superuser.com/a/213146/128124直接仅适用于后缀,但这适用于基本名称上的任意正则表达式替换:

PATH=/usr/bin find . -depth -execdir rename 's/_dbg.txt$/_.txt' '{}' \;

或仅影响文件:

PATH=/usr/bin find . -type f -execdir rename 's/_dbg.txt$/_.txt' '{}' \;

-execdir首先cd进入目录,然后仅在基本名称上执行。

在 Ubuntu 20.04 上测试,找到 4.7.0,重命名为 1.10。

方便更安全的帮手

find-rename-regex() (
  set -eu
  find_and_replace="$1"
  PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \
    find . -depth -execdir rename "${2:--n}" "s/${find_and_replace}" '{}' \;
)

GitHub 上游

用连字符“-”替换空格“ ”的示例用法。

试运行以显示什么将被重命名为什么,而无需实际执行:

find-rename-regex ' /-/g'

进行替换:

find-rename-regex ' /-/g' -v

命令解释

与 不同,awesome-execdir选项会cd在执行命令之前进入目录。rename-exec

-depth确保重命名首先发生在子级,然后在父级,以防止缺少父目录的潜在问题。

-execdir是必需的,因为重命名不能很好地与非基本名称输入路径配合使用,例如以下失败:

rename 's/findme/replaceme/g' acc/acc

PATH需要进行黑客攻击,因为它-execdir有一个非常烦人的缺点:find非常固执己见并且拒绝做任何事情,-execdir如果你的PATH环境变量中有任何相对路径,例如./node_modules/.bin,失败:

find:PATH 环境变量中包含相对路径“./node_modules/.bin”,与 find 的 -execdir 操作结合使用不安全。请从 $PATH 中删除该条目

也可以看看:https://askubuntu.com/questions/621132/why-using-the-execdir-action-is-insecure-for-directory-which-is-in-the-path/1109378#1109378

-execdir是 GNU 发现POSIX 扩展.rename基于 Perl 并来自rename包。

重命名前瞻解决方法

如果您的输入路径不是来自find,或者您已经受够了相对路径的烦恼,我们可以使用一些 Perl 前瞻来安全地重命名目录,如下所示:

git ls-files | sort -r | xargs rename 's/findme(?!.*\/)\/?$/replaceme/g' '{}'

我还没有找到一个方便的-execdir类似物xargsXargs:执行之前将工作目录更改为文件路径?

需要sort -r确保文件位于其各自的目录之后,因为较长的路径位于具有相同前缀的较短路径之后。

在 Ubuntu 18.10 中测试。

相关内容