使用find和sed替换重命名目录

时间:2014-07-07 13:11:49

标签: macos sed find

我试图用find重新命名一些目录并将其切换为基于目录名称。

示例目录名称:

rabbit_stand_a_e
rabbit_stand_a_ne

我希望这些改变为:

rabbit_a_stand_e
rabbit_a_stand_ne

所以我想基本上用_分开,然后转换$ 2和$ 3

我已经尝试了一些事情,但无法正常工作,这就是我现在所处的位置。

find . -type d -execdir mv {} `echo {} | sed -E 's/rabbit_([a-z]+)_([abc])_/rabbit_\2_\1_/'` \;

这个错误

mv: cannot move ‘rabbit_stand_a_e’ to a subdirectory of itself, ‘rabbit_stand_a_e/rabbit_stand_a_e’

1 个答案:

答案 0 :(得分:1)

问题源于find替换{}参数时,以及当shell运行子shell时(反引号中包含的命令部分)。

在运行给定命令之前,评估所有子shell。这意味着在 echo {} | sed ...'替换为文件名之前,您最终会运行{}命令,这意味着您将真正回显字符串"{}"并且将它汇总到sed。由于您的sed模式与"{}"不匹配,因此只会保持{}不变,只留下:

find . -type d -execdir mv {} {}

现在,当find运行时,它会将{}的两个匹配项替换为给定的目录名,因此会出现关于尝试将目录移动到自身的错误消息。

解决此问题的最简单方法可能是使用bash -c解释整个命令,并将参数{}传递给bash:

find . -type d -execdir bash -c 'mv $1 `echo $1 | sed -E "s/rabbit_([a-z]+)_([abc])_/rabbit_\2_\1_/"`' -- {} \;

我认为使用xargs应该有一种直截了当的方法,但目前我并不是很明显。如果我以后再想起来,我会更新我的答案(或者如果有其他人想要发表评论并表示赞赏)。


相关阅读:Subshell arguments in -exec parameter for find(1)