man ページの重要な部分は次のとおりです。
<ブロック引用>転送するファイル/ディレクトリのリストが作成されると、rsync は転送される各名前を包含/除外パターンのリストと照合して順番にチェックし、最初に一致したパターンが処理されます。除外パターンの場合、そのファイルはスキップされました。インクルード パターンの場合、そのファイル名はスキップされません。一致するパターンが見つからない場合、ファイル名はスキップされません。
要約すると:
- どのパターンとも一致しない場合、ファイルがコピーされます!
- いずれかのパターンが一致すると、アルゴリズムは終了します
また、スラッシュで終わるものはディレクトリに一致しています (find -type d
など)。
この答えを上から引き離してみましょう。
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"
<オール> .sh
をスキップしないでください ファイル
最後に、--prune-empty-directories
最初のルールで空のディレクトリがあちこちに作成されないようにします。
--include
だと思います --exclude
によって除外されるファイルのサブセットを含めるために使用されます 、それらのファイルだけを含めるのではなく、.つまり、 include について考える必要があります 除外しないことを意味します .
代わりに試してください:
rsync -zarv --include "*/" --exclude="*" --include="*.sh" "$from" "$to"
rsync バージョン 3.0.6 以降の場合、次のように順序を変更する必要があります (コメントを参照):
rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"
-m
を追加する フラグは、宛先に空のディレクトリ構造を作成することを回避します。バージョン 3.1.2 でテスト済み。
したがって、*.sh ファイルのみが必要な場合は、すべてのファイルを除外する必要があります --exclude="*"
、すべてのディレクトリ --include="*/"
を含めます すべての *.sh ファイルを含めます --include="*.sh"
.
Include/Exclude パターン ルール セクションでいくつかの良い例を見つけることができます。 マニュアルページの
もう 1 つ追加:1 つのディレクトリのみの拡張子でファイルを同期する必要がある場合 (再帰なしで) 次のような構造を使用する必要があります:
rsync -auzv --include './' --include '*.ext' --exclude '*' /source/dir/ /destination/dir/
最初の --include
のドットに注意してください . --no-r
この構造では機能しません。
編集:
貴重なコメントをくださった gbyte.co に感謝します!
編集:
-uzv
flags はこの質問とは直接関係ありませんが、普段から使用しているので含めました。
@chepner による回答は、ファイルが含まれているかどうかに関係なく、すべてのサブディレクトリをコピーします。ファイルを含まず、ディレクトリ構造を保持しているサブディレクトリを除外する必要がある場合は、
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"