大きなディレクトリツリーを再同期する方法はありますが、正規表現に一致するリーフディレクトリのみを同期しますか?

大きなディレクトリツリーを再同期する方法はありますが、正規表現に一致するリーフディレクトリのみを同期しますか?

たとえば、説明する方が簡単です。私のディレクトリ構造が次のようになると想像してください。

pics/cats/png/01.png
pics/cats/png/02.png
pics/cats/jpg/01.jpg
pics/cats/jpg/02.jpg
pics/dogs/png/01.png
pics/dogs/png/02.png
pics/dogs/jpg/01.jpg
pics/dogs/jpg/02.jpg

「pics」ディレクトリをターゲットに同期したいのですが、ターゲットではリーフディレクトリのフィルタ文字列が「png」であるとし、次のような結果が必要です。

pics/cats/png/01.png
pics/cats/png/02.png
pics/dogs/png/01.png
pics/dogs/png/02.png

また、次の結果を得たいと思います。 (pngディレクトリが不要になったため)

pics/cats/01.png
pics/cats/02.png
pics/dogs/01.png
pics/dogs/02.png

文字列「png」は任意のディレクトリに含めることができますが、リーフディレクトリ、つまり他のディレクトリを含まないディレクトリだけを「フィルタリング」したいと思います。

また、「png」ディレクトリにpng以外のファイルが含まれていても、「png」ディレクトリの内容を保存したいと思います。つまり:

pics/cats/png/01.png
pics/cats/png/02.txt
pics/cats/jpg/01.jpg
pics/cats/jpg/02.jpg
pics/dogs/png/01.txt
pics/dogs/png/02.png
pics/dogs/jpg/01.jpg
pics/dogs/jpg/02.jpg

になる:

pics/cats/png/01.png
pics/cats/png/02.txt
pics/dogs/png/01.txt
pics/dogs/png/02.png

または:

pics/cats/01.png
pics/cats/02.txt
pics/dogs/01.txt
pics/dogs/02.png

最後の注意:ディレクトリ構造は「n」の深さにすることができます。つまり:

pics/cats/house/tabby/png/01.png
pics/cats/house/tabby/png/02.txt
pics/cats/house/tabby/jpg/01.jpg
pics/cats/house/tabby/jpg/02.jpg

になる:

pics/cats/house/tabby/png/01.png
pics/cats/house/tabby/png/02.txt

または:

pics/cats/house/tabby/01.png
pics/cats/house/tabby/02.txt

簡単な方法が存在しない場合は、bashスクリプトを作成してこれを行うことができると確信しています。しかし、これは一般的ではありませんが、時々現れると確信するユースケースのようです。これには名前とフラグがあります。

答え1

あなたはできますすべてのリーフノードをインポートする、これをフィルタリングしgrep、結果をファイルに保存するために使用します。

次に、rsyncこの--files-fromオプションを使用して実行します。

これらは単なる基本です。たとえば、直接フィルタリングawkしたり 。xargs簡潔または効率的に説明するのではなく、関連するステップを示すことです。

階層のルートにある場合:

$ find . -type d | sort | awk '$0 !~ last "/" {print last} {last=$0} END {print last}' | grep '/png$' > /tmp/dirs_rsync.txt

$ rsync -av --files-from=/tmp/dirs_rsync.txt . /your/destination/folder

関連情報