如何修改命令实现目录及子目录下文件名指定内容的递归重命名
递归批量重命名的实现方案
你原来的命令只能匹配当前目录下的文件,要实现全目录递归处理,推荐以下两种兼容性较好的方案:
方案1:通用find方案(适用于所有bash环境)
该方案是跨环境兼容性最好的写法,无需额外依赖:
find . -depth -name "*foo*" -exec bash -c 'for f; do mv -- "$f" "${f//foo/bar}"; done' _ {} +
参数说明:
-depth强制find从最深层的子目录开始向上处理,避免先修改上层目录名称后,程序找不到下层文件路径的问题-name "*foo*"匹配所有名称包含foo的文件、目录- 内嵌的bash调用用来批量处理find返回的结果,比逐次调用
mv执行效率更高 --用来兼容以-开头的文件名,避免mv误将文件名识别为命令参数
方案2:zsh环境极简写法
如果使用的是zsh shell,开启globstar选项后即可直接用**匹配全层级路径:
setopt globstar # 加(od)参数指定从最深目录开始处理 for f in **/*foo*(od); do mv -- "$f" "${f//foo/bar}"; done
前置校验建议
正式执行修改前,建议先把命令中的mv替换为echo mv,预览所有即将执行的重命名操作,确认匹配规则和修改结果无误后再换回mv执行,避免误操作:
# 预览修改效果,不会实际修改文件名 find . -depth -name "*foo*" -exec bash -c 'for f; do echo mv -- "$f" "${f//foo/bar}"; done' _ {} +
如果你的系统预装了perl版本的rename工具,也可以用更简洁的写法:
find . -depth -name "*foo*" -exec rename 's/foo/bar/g' {} +
注:util-linux自带的rename语法与上述写法不同,环境不确定的情况下优先使用find+bash的通用方案
内容的提问来源于stack exchange,提问作者Robin Gowdy
相关产品推荐
相关产品推荐

