我有一个具有以下布局的目录(其中的布局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.jpg
、
another 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
.
免责声明:我已经对此进行了测试,但并不彻底。我不保证这会完美地工作。在尝试上述命令之前,您应该进行完整备份。