对于所有目录 - 使用前缀重命名所有子目录

对于所有目录 - 使用前缀重命名所有子目录

我目前有 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 {} \;

笔记:

  1. 为了形成目标目录的名称,我们需要删除./目录名称中的首字母。为了实现这一点,我们使用 shell 的前缀去除: ${1#./}

  2. 我们使用-execdir而不是-exec因为它在命令运行时重命名目录的情况下更稳健。

  3. 在表达式 中bash -c '...' mover {},bash 运行单引号中的命令,并$0分配给文件名. 除非 shell 需要写入错误消息,否则不使用。mover$1{}$0

  4. 这段代码不需要任何 bash 功能。可以使用任何 POSIX shell。

  5. 如果您想在运行命令之前测试该命令以确保它执行所需的操作,请echo按如下所示添加:

    find . -maxdepth 2 -mindepth 2 -type d -execdir bash -c 'echo mv "$1" "./album_${1#./}"' mover {} \;
    

有关注意事项-exec mv '{}' album_'{}'

  1. 不要引用{}. find处理那个。

  2. 由于 提供的文件名将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_|' {} +
  • .*/匹配/目录路径中的最后一个
  • 通过使用\Klookbehind,我们可以避免在这种情况下需要捕获组
  • 默认情况下,可以跳过 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*/*

相关内容