将文件向上移动几个目录以获取具有相似布局的多个目录

将文件向上移动几个目录以获取具有相似布局的多个目录

我有一个具有以下布局的目录(其中的布局Directory 1在其他目录中重复):Directory <num>

父目录
   目录1
      一些目录
         另一个目录
            <许多文件>
   目录2
   目录3
   目录4

我想通过在文件前面加上前缀来重命名这些文件,并将它们向上移动 3 个目录,以便它们位于 下,并删除原始(现在为空)目录,如下所示:Directory <num>Parent directory

父目录
   目录1_<许多文件>
   目录2
   目录3
   目录4

我怎么能这么做呢?

以下内容来自于类似的问题

find . -mindepth 2 -name '*.jpg' -exec rename -n 's!/([^/]+)$!_$1!' {} +

将文件重命名为第一个父目录:

父目录
   目录1
      另一个目录_<许多文件>
   目录2

答案1

首先,我无法重现您所显示的命令声称的结果。我将文件重命名为another directory_file1.jpganother directory_file2.jpg等, 但仍处于 some directory 目录。

其次,由于目录结构的深度,您应该使用-mindepth 4而不是2.第三,我强烈鼓励您使用-type f.只要您使用-name '*.jpg',您可能就找不到任何目录。但六到八周后,你会看到这个并想“我希望它适用于我的所有文件 - 我不需要说-name '*.jpg'”,然后你就会把它拿出来。然后,如果您没有-type f,该find命令可能会开始查找目录并重命名它们。在扫描目录树时对其进行修改会导致灾难(就像众所周知的“在我们仍在建造飞机时驾驶飞机”)。

第四,将文件向上移动三级并在其名称前加上前缀的重命名命令是Directory <num>_

重命名 -n 's!/[^/]+/[^/]+/([^/]+)$!_$1!'
        (可选)

因为/[^/]+代表目录级别,所以我只添加了两个副本。

警告:正如我所说,这会将文件向上移动三个级别。如果目录树中有任何比该深度更深的文件,它们将不会被重命名为顶层;它们可能会被重命名为类似的名称Directory 3/some directory_file3.jpg

但事实证明这很容易解决。将文件移动到顶层无论它在什么深度,并在其名称前添加 前缀,只需使用Directory <num>_

s!(\./[^/]+)/.*/([^/]+)$/$1_$2/!

长话短说

所以,

最终命令是

find . -mindepth 4 -type f -exec rename -n 's!/[^/]+/[^/]+/([^/]+)$!_$1!' {} +

-name '*.jpg'如果需要的话可以添加。-n当跟踪输出显示它正在做正确的事情时删除。

请注意,这可能会导致文件名冲突。如果你有文件

Directory 1/some directory/another directory/sunrise.jpg

Directory 1/some directory/another directory/mountains/sunrise.jpg

该命令将尝试将它们都重命名为Directory 1_sunrise.jpg.幸运的是,该rename程序似乎足够聪明/友好,在这种情况下不会造成任何伤害。它看到的第一个这样的文件将(可能)被重命名;其他人将留在原处(并且您将收到通知)。 (您可以使用-f--force来强制覆盖现有文件。)但请记住,某些其他程序(例如 mv)的默认操作不太友好。


对于更新的问题(“如何在文件名中包含所有目录名?”):这有点棘手。我将明确假设我们正在搜索../,因此所有路径名都以.开头。我发现佩莱克斯普的参数rename 实际上可以包含多个字符串修改命令。因此,我们可以将所有文件移动到顶层,并在其名称前加上路径中所有目录名称的前缀

s!^\./!!;s!/!_!g

这也存在文件名冲突的可能性。

Directory 1/abc/def_ghi/sunrise.jpg

Directory 1/abc_def/ghi/sunrise.jpg

将(可能)都重命名为Directory 1_abc_def_ghi_sunrise.jpg.


免责声明:我已经对此进行了测试,但并不彻底。我不保证这会完美地工作。在尝试上述命令之前,您应该进行完整备份。

相关内容