我尝试了几种方法来查找并重命名目录中一些包含反斜杠的文件(请注意,这些从网络应用程序生成的文件没有引号)。我尝试过查找和替换,但它们似乎在父级别失败。基本上就像它重命名父文件夹,但随后无法下降到子文件夹,因为它在下降时引用了较旧的父名称?
文件夹结构:
'ano\ther' -> 'chi\ld'
当我跑步时:
for file in `find . -name '*\\\*'`; do mv -v "$file" "${file/\\/}"; done`
或者
find . -exec rename 's/\\//g' {} +
或者
find . -name "*\\\*" -exec rename 's/\\//g' {} +
他们几乎都说同样的错误,但确实重命名了父目录或当前目录,只是在降序时失败。
Can't rename ./ano\ter/yo\yo ./anoter/yoyo: No such file or directory
我的命令中会缺少什么?
答案1
你需要:
- 不要像那样循环
find
输出 - 避免已弃用的
`...`
命令替换形式 - 在叶子所在的分支之前重命名叶子
- 仅删除
\
文件名中的 s,而不是其完整路径 - 当需要文字反斜杠时避免双引号
所以:
find . -depth -name '*\\*' -exec rename -d 's/\\//g' {} +
(这里假设基于 perl 的变体rename
,并且接受该-d
选项仅重命名基本名称)。
或者:
find . -depth -name '*\\*' -exec zsh -c '
for file do
mv -v -- $file $file:h/${file:t:gs/\\/}
done' zsh {} +
或者在 zsh 中,只需:
autoload zmv
zmv -v '(**/)(*\\*)(#qD)' '$1$2:gs/\\/'
这里使用 csh 样式$var:s/string/replacement/
(withg
重复),但如果您愿意,也可以使用 ksh 样式${var//pattern/replacement}
(with//
重复形式)。
zmv
默认情况下进行深度优先遍历,因为这就是您通常想要的,(#qD)
同时还要考虑隐藏文件。zmv
如果检测到某些问题,例如同时存在 aa\bc
和a\b\c
文件,它们都会被重命名为abc
.
答案2
我猜想出现该错误消息是因为您试图同时删除两个“es”,而目录“./anoter”可能不存在。
您只需添加-type f
到 find.txt 文件中即可处理目录结构中的所有文件。但是,如果您知道只有一级子目录(或者至少一级名称中只有 'es),那么您仍然拥有这些目录,您可以使用 find-type d
来查找,但是如果您有例如,ano\ther/d\ir/
该命令将因同样的错误而失败。
您可能会得到一些东西来使用 using-execdir
而不是 on -exec
(和 using -depth
),但我从未尝试过-execdir
,所以我只是快速阅读手册页的建议。想一想,我什至不确定如果这样做的话是否需要先处理文件。