私は多くのファイルとその中にテキストファイルを含む多くのディレクトリを持っています。こんな感じ
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-dirs
rsync
使用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
。