按深度标准将文件向上移动一个目录

按深度标准将文件向上移动一个目录

我有一个如下所示的目录树(简化后,实际上有数百个文件夹):

.
├── a
│   └── b
│       └── a.h5
├── b
│   ├── b
│   │   └── e.h5
│   └── c
│       ├── a.h5
│       └── b.h5
├── c
│   └── b
│       └── a.h5
├── d
│   ├── a.h5
│   └── e.h5
└── e
    └── e.h5

基本上,有些.h5文件的深度为 1(例如d/a.h5, e/e.h5),有些文件的深度为 2(例如b/b/e.h5, b/c/b.h5, ...)

我只想向上移动深度为 2 的文件,以便它们都位于深度 1,如下所示:

.
├── a
│   └── a.h5
├── b
│   ├── e.h5
│   ├── a.h5
│   └── b.h5
├── c
│   └── a.h5
├── d
│   ├── a.h5
│   └── e.h5
└── e
    └── e.h5

我知道这与*/*/*.h5我感兴趣的文件相匹配(通过测试ls */*/*.h5),但我尝试过mv */*/*.h5 */*.h5,结果弄得一团糟。

重复的文件最好通过重命名来处理,但提示也可以。我应该如何进行?

PS:我见过:

但它们都适用于单个目录。

答案1

这应该是一个开始:

find . -mindepth 3 -maxdepth 3 -type f -execdir mv -i -v {} .. \;

要求mv -i覆盖现有文件。-execdir在执行命令之前更改文件的目录。

答案2

从你的目录结构来看:

$ tree
.
├── a
│   └── b
│       └── a.h5
├── b
│   ├── b
│   │   └── e.h5
│   └── c
│       ├── a.h5
│       └── b.h5
├── c
│   └── b
│       └── a.h5
├── d
│   ├── a.h5
│   └── e.h5
└── e
    └── e.h5

12 directories, 8 files

使用这个for循环:

$ for f in */*/*.h5; do mv -v -- "$f" "${f%/*}/../"; done
»a/b/a.h5“ -> »a/b/../a.h5“
»b/b/e.h5“ -> »b/b/../e.h5“
»b/c/a.h5“ -> »b/c/../a.h5“
»b/c/b.h5“ -> »b/c/../b.h5“
»c/b/a.h5“ -> »c/b/../a.h5“

结果:

$ tree
.
├── a
│   ├── a.h5
│   └── b
├── b
│   ├── a.h5
│   ├── b
│   ├── b.h5
│   ├── c
│   └── e.h5
├── c
│   ├── a.h5
│   └── b
├── d
│   ├── a.h5
│   └── e.h5
└── e
    └── e.h5

12 directories, 8 files

解释:

for f in */*/*.h5; do mv -v -- "$f" "${f%/*}/../"; done
  • for f in */*/*.h5循环遍历所有需要的文件
    • mv -v --详细地感动他们。--防止带破折号的文件名被解释为参数。
    • "$f"原始文件名
    • ${f%/*}/../添加的包含该文件的目录的名称../。该路径被解释为“向上一个目录”。

答案3

尝试

 for x in */*/*.h5
 do
    mv "$x" "$(dirname $(dirname $x))"
 done

如果目录名称中没有奇怪的字符。

或者,另一种选择:

ls */*/*.h5 | awk -F/ '{print "mv \"%s\"  \"%s/%s\" \n",$0,$1,$3 ;}' | bash

您可以删除| bash以获取预览。

相关内容