我试图用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’
答案 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
应该有一种直截了当的方法,但目前我并不是很明显。如果我以后再想起来,我会更新我的答案(或者如果有其他人想要发表评论并表示赞赏)。