includeオプションを使用して特定のタイプのファイルのみをrsyncでコピー


110

次のbashスクリプトを使用して、特定の拡張子(この場合は* .sh)のファイルのみをコピーしますが、それでもすべてのファイルにコピーされます。どうしましたか?

from = $ 1
to = $ 2

rsync -zarv --include = "*。sh" $ from $ to

4
厳密に関連しているわけではありませんが、$ from / $ toを引用することをお勧めします。これを行わないと、位置引数1/2にスペースが含まれている場合に予期しない結果が生じる可能性があります。
Kjetil Joergensen 2012年

コマンドが機能しない理由を理解しましたか?
チャーリーパーカー

@CharlieParker:を使用する必要がありrsyncますか?これはシェルの内部で非常にうまく達成できますか?
2018年

この質問とその回答に欠けているのは、1種類のファイルのみを送信したい再帰ディレクトリがある場合にコマンドを作成する方法です。ターゲットディレクトリに対してのみ機能するようです...
Charlie Parker

回答:


198

これらのファイルだけではなく、--includeによって除外されているファイルのサブセットを含めるために使用されていると思い--excludeます。言い換えれば、含めることは除外しないことの意味について考える必要があります。

代わりに試してください:

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"

manページのセクションInclude / Exclude Pattern Rulesにいくつかの良い例があります。


10
すべてのサブディレクトリが取得されますが、rsyncを実行するサブディレクトリに.shファイルがある場合は、-include = "* /"も使用する可能性があります。
Kjetil Joergensen 2012年

50
私はずっと前にmacportsから入手したrsyncバージョン3.0.7でこれを試しましたが、includes / excludesのこの順序では機能しませんでした。これは私が(OPのために適合)私のために働いたことになってしまったものです:rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"
Bijou Trouvaille 2013年

3
rsync 3.0.9を試しましたが、うまくいきませんでした。ビジューは正しい、順序は適切ではありません(最初に--include=\*.sh次に--exclude=\*
TrueY

3
いつでも[編集]をクリックして、回答への編集を提案できます:)
Achal Dave

2
インクルード/エクスクルードの順序では機能しませんが、Bijou Trouvailleによって提案された順序で機能します
John Smithオプション

56

@chepnerによる回答では、ファイルが含まれているかどうかにかかわらず、事実に関係なくすべてのサブディレクトリがコピーされます。ファイルを含まず、ディレクトリ構造を保持しているサブディレクトリを除外する必要がある場合は、

rsync -zarv  --prune-empty-dirs --include "*/"  --include="*.sh" --exclude="*" "$from" "$to"

1
これは私にとっての要件でした:「ファイルを含まないサブディレクトリを除外し、それでもディレクトリ構造を保持する必要がある場合」+1
Juuso Ohtonen

1
--includeの順序をどのようにして知ったのですか?
チャーリーパーカー

1
1種類のファイルだけを送信したい再帰ディレクトリがある場合、コマンドはどのように作成されますか?ターゲットディレクトリに対してのみ実行するようです。
チャーリーパーカー

15

さらにもう1つ:拡張子でファイルを1つのディレクトリのみ(再帰なしで)同期する必要がある場合は、次のような構造を使用する必要があります。

rsync -auzv --include './' --include '*.ext' --exclude '*' /source/dir/ /destination/dir/

最初のドットに注意してください--include--no-rこの構造では機能しません。

編集:

貴重なコメントをありがとうgbyte.co!


1
フラグの順序と、フラグを含めるために必要なものをどのようにして知りましたか?
チャーリーパーカー

1
rsyncは使用しているため@CharlieParkerは、includeexclude彼らはで指定された順序でオプション。これに加えて、それは最初に一致した1で停止します。したがって、--exclude '*'この例で最初にを指定した場合、rsyncは何もしません。詳細については、男性を参照してください。
Serge Roussak

各フラグが何をしているか説明してくれませんか?最初のフラグ-- include './' は、ソースディレクトリパスにすべてを含めると言っていますか?次に、次の `--include '.ext'`は、指定されたソースパスに特定のファイルをインクルードし.ext、excludeは他に何も送信しないと言います--exclude '*'か?あれは正しいですか?
チャーリーパーカー

1
1種類のファイルだけを送信したい再帰ディレクトリがある場合、コマンドはどのように作成されますか?ターゲットディレクトリに対してのみ実行するようです。
チャーリーパーカー

1
これをありがとう!する必要があるか--include '*.ext'--include '.ext'
どう

13

manページの重要な部分は次のとおりです。

転送するファイル/ディレクトリのリストが作成されると、rsyncは転送する各名前をインクルード/除外パターンのリストに対して順番にチェックし、最初に一致したパターンが処理されます。除外パターンの場合、そのファイルはスキップされました。インクルードパターンの場合、そのファイル名はスキップされません。一致するパターンが見つからない場合、ファイル名はスキップされません。

要約する:

  • どのパターンにも一致しない場合は、ファイルがコピーされます!
  • いずれかのパターンが一致すると、アルゴリズムは終了します

また、スラッシュで終わるものは、(一致するようfind -type dに)ディレクトリに一致します。

この答えを上から引き離してみましょう。

rsync -zarv  --prune-empty-dirs --include "*/"  --include="*.sh" --exclude="*" "$from" "$to"
  1. ディレクトリをスキップしないでください
  2. .shファイルをスキップしないでください
  3. すべてをスキップ
  4. (暗黙的に、何もスキップしないでください。ただし、上記のルールにより、デフォルトのルールが実行されなくなります。)

最後に、--prune-empty-directoriesは最初のルールがいたるところに空のディレクトリを作成しないようにします。


何が起こっているのか説明していただきありがとうございます。これで、コマンドを忘れない可能性が大幅に向上しました。
MohamedEzz

3
「パターンが一致するとアルゴリズムは終了します」 —これは重要であり、ここで行ったように、より高い評価の回答のどれもそれを明確かつ事前に説明していません。もちろん、これ manページにあります。すべてを注意深く読み、私はそれを見てきました。それでも、感謝します
TheDudeAbides

0

誰かがこれを探している場合...私は特定のファイルとフォルダのみをrsyncしたいと思っていて、次のコマンドでそれを行うことができました: rsync --include-from=rsync-files

rsync-filesの場合:

my-dir/
my-file.txt

- /*

0

この便利な関数を書いて、私のbashスクリプトまたはに入れてください~/.bash_aliases。Linuxでbashを使用してローカルで同期をテストし、awkインストールしました。できます

selrsync(){
# selective rsync to sync only certain filetypes;
# based on: https://stackoverflow.com/a/11111793/588867
# Example: selrsync 'tsv,csv' ./source ./target --dry-run
types="$1"; shift; #accepts comma separated list of types. Must be the first argument.
includes=$(echo $types| awk  -F',' \
    'BEGIN{OFS=" ";}
    {
    for (i = 1; i <= NF; i++ ) { if (length($i) > 0) $i="--include=*."$i; } print
    }')
restargs="$@"

echo Command: rsync -avz --prune-empty-dirs --include="*/" $includes --exclude="*" "$restargs"
eval rsync -avz --prune-empty-dirs --include="*/" "$includes" --exclude="*" $restargs
}

利点:

より多くの引数を追加したい場合(つまり--dry-run)は、短くて便利で拡張可能です。

例:

selrsync 'tsv,csv' ./source ./target --dry-run
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.