複数の異なるサブフォルダを1つ下のレベルに移動するには?

複数の異なるサブフォルダを1つ下のレベルに移動するには?

私は次のような構造を持つ多数のファイルを持っています:/base/にあるすべてのファイル、2つの「ランダム」文字を持つ4つのフォルダ、そして互いに関連する一連のファイル。

例:

/base/ab/12/13/37/file1.txt
/base/ab/12/13/37/file2.txt
/base/ab/12/13/37/file3.txt
/base/cd/b8/e2/a1/other1.txt
.... 
/base/cd/b8/e2/a1/other52.txt
/base/af/f3/45/9e/third1.txt
/base/af/f3/45/9e/third2.txt

など

ほとんどの構造を維持しますが、私のファイルが属する最後に追加(extra_folder)フォルダを追加したいと思います。したがって、上記の内容を次のように変更してください。

/base/ab/12/13/37/extra_folder/file1.txt
/base/ab/12/13/37/extra_folder/file2.txt
/base/ab/12/13/37/extra_folder/file3.txt
/base/cd/b8/e2/a1/extra_folder/other1.txt

私はシェルスクリプトと移動コマンドが必要になると予想しました。

とても感謝しています。

答え1

これが私たちが始めるところです:

$ tree base/
base/
|-- ab
|   `-- 12
|       `-- 13
|           `-- 37
|               |-- file1.txt
|               |-- file2.txt
|               `-- file3.txt
|-- af
|   `-- f3
|       `-- 45
|           `-- 9e
|               |-- third1.txt
|               `-- third2.txt
`-- cd
    `-- b8
        `-- e2
            `-- a1
                |-- other1.txt
                `-- other52.txt

12 directories, 7 files

まず、新しいディレクトリを追加します。

$ find base -type d -mindepth 4 -maxdepth 4 -exec mkdir {}/extra_folder ';'

我々は、4番目のレベルで新しいディレクトリを作成するためにのみ-mindepth 4を使用します。-maxdepth 4そうでない場合は、-mindepth 4より高いレベルの新しいディレクトリが得られます。新しいディレクトリがないと、パス名が長すぎてディレクトリを作成できなくなる-maxdepth 4まで、そのディレクトリ自体が新しいディレクトリで埋められます。find

ディレクトリはから呼び出して作成されextra_folderます。今私たちはmkdir-exec

$ tree base/
base/
|-- ab
|   `-- 12
|       `-- 13
|           `-- 37
|               |-- extra_folder
|               |-- file1.txt
|               |-- file2.txt
|               `-- file3.txt
|-- af
|   `-- f3
|       `-- 45
|           `-- 9e
|               |-- extra_folder
|               |-- third1.txt
|               `-- third2.txt
`-- cd
    `-- b8
        `-- e2
            `-- a1
                |-- extra_folder
                |-- other1.txt
                `-- other52.txt

15 directories, 7 files

次にファイルを下に移動します。

$ find base -maxdepth 5 -type f -execdir mv {} extra_folder ';'

これにより、5番目のレベルディレクトリまたはその下にある一般的なファイルを見つけることができますbase(最下位レベルにのみファイルがあると仮定します)。その後、見つかったファイルが存在するディレクトリ内-execdirでコマンドを実行するために使用されます(見つかったファイルのデフォルト名になります)。mv{}

私たちはついに得ます

$ tree base/
base/
|-- ab
|   `-- 12
|       `-- 13
|           `-- 37
|               `-- extra_folder
|                   |-- file1.txt
|                   |-- file2.txt
|                   `-- file3.txt
|-- af
|   `-- f3
|       `-- 45
|           `-- 9e
|               `-- extra_folder
|                   |-- third1.txt
|                   `-- third2.txt
`-- cd
    `-- b8
        `-- e2
            `-- a1
                `-- extra_folder
                    |-- other1.txt
                    `-- other52.txt

15 directories, 7 files

一度に:

$ find base -type f \
    -execdir sh -c '[ ! -d "$1" ] && mkdir "$1"; mv "$2" "$1"' sh 'extra_folder' {} ';'

extra_folderこれにより、開始位置に関係なくすべての一般ファイルを見つけて、名前付きディレクトリに移動します。このコマンドを複数回実行すると、コマンドはますます下に移動します。

次のミニスクリプトが呼び出されます-execdir

[ ! -d "$1" ] && mkdir "$1"
mv "$2" "$1"

フォルダ名は、ファイル名は$1として呼び出され$2、フォルダが存在しない場合はフォルダを作成し、ファイルをそのフォルダに移動します。

関連情報