我目前有 2000 个用户目录,每个目录都有子目录。
用户_1
---> 孩子1
---> 孩子2
用户_29
---> child37
---> 孩子56
ETC
我需要遍历所有用户文件夹,然后遍历每个子文件夹,并使用前缀“album_”重命名子文件夹。我的最终结构应该是:
用户_1
---> album_child1
---> album_child2
用户_29
---> album_child37
---> album_child56
我可以使用以下命令重命名用户文件夹:
for f in * ; do mv "$f" user_"$f" ; done;
我一直在尝试几种不同的方法来重命名子目录,例如:
find . -maxdepth 2 -mindepth 2 -type d -exec mv '{}' album_'{}'
上述查询的第一部分返回我需要重命名的所有目录('find . -max深度 2 -min深度 2 -type d')。
如何在 -exec 函数中访问目录名称,然后为其添加前缀?
答案1
尝试:
find . -maxdepth 2 -mindepth 2 -type d -execdir bash -c 'mv "$1" "./album_${1#./}"' mover {} \;
笔记:
为了形成目标目录的名称,我们需要删除
./
目录名称中的首字母。为了实现这一点,我们使用 shell 的前缀去除:${1#./}
。我们使用
-execdir
而不是-exec
因为它在命令运行时重命名目录的情况下更稳健。在表达式 中
bash -c '...' mover {}
,bash 运行单引号中的命令,并$0
分配给文件名. 除非 shell 需要写入错误消息,否则不使用。mover
$1
{}
$0
这段代码不需要任何 bash 功能。可以使用任何 POSIX shell。
如果您想在运行命令之前测试该命令以确保它执行所需的操作,请
echo
按如下所示添加:find . -maxdepth 2 -mindepth 2 -type d -execdir bash -c 'echo mv "$1" "./album_${1#./}"' mover {} \;
有关注意事项-exec mv '{}' album_'{}'
不要引用
{}
.find
处理那个。由于 提供的文件名将
find
以 开头./
,因此该表单album_{}
将不会成功。
例子
让我们考虑一下这些目录:
$ ls *
user1:
child1 child2
user2:
child1 child2
Press any key to continue...
现在。让我们运行命令并查看新的目录名称:
$ find . -maxdepth 2 -mindepth 2 -type d -execdir bash -c 'mv "$1" "./album_${1#./}"' mover {} \;
$ ls *
user1:
album_child1 album_child2
user2:
album_child1 album_child2
答案2
如果您有perl
基础rename
find -maxdepth 2 -mindepth 2 -type d -exec rename -n 's|.*/\K|album_|' {} +
.*/
匹配/
目录路径中的最后一个- 通过使用
\K
lookbehind,我们可以避免在这种情况下需要捕获组 - 默认情况下,可以跳过 in,因为它
.
适用于当前目录find .
find
-n
显示正确的重命名后,从重命名中删除选项
例子:
$ ls *
user_1:
child1 child2
user_29:
child37 child56
$ find -maxdepth 2 -mindepth 2 -type d -exec rename -n 's|.*/\K|album_|' {} +
rename(./user_29/child37, ./user_29/album_child37)
rename(./user_29/child56, ./user_29/album_child56)
rename(./user_1/child2, ./user_1/album_child2)
rename(./user_1/child1, ./user_1/album_child1)
$ find -maxdepth 2 -mindepth 2 -type d -exec rename 's|.*/\K|album_|' {} +
$ ls *
user_1:
album_child1 album_child2
user_29:
album_child37 album_child56
答案3
我通常不直接使用 -exec,因为如果出现问题,调试起来会更加困难。只需find
编写一个脚本,您可以在执行之前查看该脚本:
find . -maxdepth 2 -mindepth 2 -type d -printf 'mv "%P" "%h/album_%f"\n' > /tmp/rename.sh sh /tmp/rename.sh
答案4
如果我们安装了基于 perl 的重命名,
rename 's!(.*/)!$1album_! if(-d $_)' user*/*