如何从最底层向上修改目录路径名,解决find+rename处理多层特殊字符目录失败的问题
如何从最底层向上修改目录路径名,解决find+rename处理多层特殊字符目录失败的问题
这个场景我太熟悉了!默认情况下find是从上到下遍历目录的,改了上层目录的名字之后,后面要处理的深层目录路径直接就失效了,自然会报"No such file or directory"。你的思路完全正确——从最底层往上处理就能解决这个问题,而且用find本身就可以实现,不需要额外的复杂工具。
核心解决方案:用find的-depth选项实现从下到上遍历
find有个非常实用的-depth参数,它会让find先处理子目录,再处理父目录,完美匹配我们"从底往上改"的需求。把你的命令加上这个参数就行:
find . -type d -depth -execdir /usr/local/bin/rename "s/'/’/g" '{}' +
为什么这个方法管用?
拿你提到的路径/data/videos/john's pics/folder/last year's bday/folder/举例:
- 加了
-depth之后,find会最先定位到最内层的last year's bday目录,先把它改成last year’s bday,这时候外层的路径还没动,操作完全有效; - 接着处理上一层的
john's pics目录,改成john’s pics,这时候内层的目录已经是新名字了,路径依然存在; - 整个过程中,每一次修改的目录都是当前存在的有效路径,不会出现找不到文件的错误。
扩展:一次性处理多个特殊字符替换
如果需要同时替换多种特殊字符(比如?转中文?、:转中文:),可以把多个正则表达式合并到同一个rename命令里,用分号分隔(注意正则里的特殊字符要转义,比如?要写成\?,因为它是正则元字符):
find . -type d -depth -execdir /usr/local/bin/rename "s/'/’/g; s/\?/?/g; s/:/:/g" '{}' +
额外提醒
- 建议先在测试目录里跑一遍命令验证效果,确认没问题再在真实数据上操作;
- 确保你用的确实是Aristotle Pagaltzis的Perl版
rename,有些系统自带的rename是简化版,不支持多正则替换的语法。
备注:内容来源于stack exchange,提问作者lucasart
相关产品推荐
相关产品推荐

