![在 Linux 中递归重命名文件(更改扩展名)](https://linux22.com/image/1257057/%E5%9C%A8%20Linux%20%E4%B8%AD%E9%80%92%E5%BD%92%E9%87%8D%E5%91%BD%E5%90%8D%E6%96%87%E4%BB%B6%EF%BC%88%E6%9B%B4%E6%94%B9%E6%89%A9%E5%B1%95%E5%90%8D%EF%BC%89.png)
如何以递归方式重命名目录中的所有文件,将一个文件扩展名更改为另一个文件扩展名,以用于数千个子文件夹中的数千个文件?我看到很多命令几乎可以完成我想要的操作,但并不完全如此。
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}" '{}' \;
)
用连字符“-”替换空格“ ”的示例用法。
试运行以显示什么将被重命名为什么,而无需实际执行:
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 中删除该条目
-execdir
是 GNU 发现POSIX 扩展.rename
基于 Perl 并来自rename
包。
重命名前瞻解决方法
如果您的输入路径不是来自find
,或者您已经受够了相对路径的烦恼,我们可以使用一些 Perl 前瞻来安全地重命名目录,如下所示:
git ls-files | sort -r | xargs rename 's/findme(?!.*\/)\/?$/replaceme/g' '{}'
我还没有找到一个方便的-execdir
类似物xargs
:Xargs:执行之前将工作目录更改为文件路径?
需要sort -r
确保文件位于其各自的目录之后,因为较长的路径位于具有相同前缀的较短路径之后。
在 Ubuntu 18.10 中测试。