すべての種類のファイルを見つけて{another_dir}/{dir_files_are_at}/{file}に移動するには?

すべての種類のファイルを見つけて{another_dir}/{dir_files_are_at}/{file}に移動するには?

私は多くのファイルとその中にテキストファイルを含む多くのディレクトリを持っています。こんな感じ

MainDir
|------dir1
|       |-------file1
|       |-------file2
|       |-------file3.txt
|------dir17
|       |-------file23
|       |-------file34
|       |-------file52.txt
|       |-------file65

各ディレクトリのファイル数はランダムであり、txtファイルが1つあるか存在しません。
すべてのtxtファイルをMainDir内の "txtFiles"ディレクトリに移動する必要があり、各txtファイルは元のディレクトリと同じ名前のサブディレクトリに存在する必要があります(txtFilesディレクトリのサブディレクトリは存在しないため、作成する必要があります)。します

MainDir
|------dir1
|       |-------file1
|       |-------file2
|------dir17
|       |-------file23
|       |-------file34
|       |-------file65
|------txtFiles
|       |-------dir1
|       |        |-------file3.txt
|       |-------dir17
|       |        |-------file52.txt

find命令で行う方法はありますか?

また、一部のファイル名とディレクトリ名にはスペースが含まれています。

答え1

$ tree
.
`-- MainDir
    |-- dir1
    |   |-- notes.txt
    |   |-- some_file-1
    |   |-- some_file-2
    |   `-- some_file-3
    `-- dir17
        |-- README.txt
        |-- some_file-1
        |-- some_file-2
        `-- some_file-3

3 directories, 8 files

使用rsync:

$ rsync -a --include '*.txt' --exclude '*/*' MainDir/ MainDir/txtFiles/
$ tree
.
`-- MainDir
    |-- dir1
    |   |-- notes.txt
    |   |-- some_file-1
    |   |-- some_file-2
    |   `-- some_file-3
    |-- dir17
    |   |-- README.txt
    |   |-- some_file-1
    |   |-- some_file-2
    |   `-- some_file-3
    `-- txtFiles
        |-- dir1
        |   `-- notes.txt
        `-- dir17
            `-- README.txt

6 directories, 10 files

このコマンドは、ファイル名サフィックスを含む--include '*.txt'すべてのファイルを含み、他のファイルを除外するために使用されます。またはを使用すると、ソース層のコピーされた部分コピーがターゲットに作成されます。.txt--exclude '*/*'-a--archive

このコマンドを再実行すると、空のMainDir/txtFiles/txtFilesディレクトリが作成されます。通話にまたはを追加すると、-mこれを防ぐことができます。--prune-empty-dirsrsync


使用find(内からMainDir):

$ find . -type f -name '*.txt' ! -path '*/txtFiles/*' \
    -exec sh -c 'for n; do
                     d="txtFiles/${n%/*}";
                     mkdir -p "$d" && cp "$n" "$d"
                 done' sh {} +

*.txtこれにより、ディレクトリにはありませんが、名前が一致するtxtFilesすべての一般的なファイルが検索されます。

見つかった各ファイル名のパスに対して、パスのディレクトリ部分がそのパスの下に作成され、ファイルがtxtFilesそこにコピーされます。

rsyncこの方法とこの方法の唯一の違いは、指定されたrsync名前と一致する非伝統的なファイルをコピーできることです(パイプという名前のディレクトリなど)find〜しなければならない内部で実行しますMainDir

関連情報