次のディレクトリツリーがあります(簡単に言えば、文字通り何百ものフォルダがあります)。
.
├── 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:私が見たものは次のとおりです。
- https://superuser.com/questions/62141/how-to-move-all-files-from-current-directory-to-upper-directory
- ファイルをディレクトリに安全に一括移動する方法は?
しかし、それらはすべて単一のディレクトリで動作します。
答え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%/*}/../
ファイルを含む追加されたディレクトリの名前../
。パスは「1つのディレクトリの上」と解釈されます。
答え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
とプレビューが表示されます。