Shell-Script

按深度標準按目錄向上移動文件

  • October 27, 2015

我有一個看起來像這樣的目錄樹(簡化,實際上有數百個文件夾):

.
├── 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:我看過:

但它們都適用於單個目錄。

從您的目錄結構開始:

$ 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%/*}/../添加的包含文件的目錄的名稱../。該路徑被解釋為“一個目錄向上”。

這應該是一個開始:

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

要求mv -i覆蓋現有文件。-execdir在執行命令之前更改文件的目錄。

引用自:https://unix.stackexchange.com/questions/238933