web-dev-qa-db-ja.com

Rsyncを使用して特定のサブディレクトリ(複数のディレクトリにある同じ名前)のみをコピーする方法

サーバー1にそのようなディレクトリ構造があります:

  • データ
    • company1
      • unique_folder1
      • other_folder
      • ...
    • company2
      • unique_folder1
      • ...
    • ...

そして、このフォルダー構造をサーバー2に複製しますが、unique_folder1のディレクトリ/サブディレクトリのみをコピーします。つまり結果として:

  • データ
    • company1
      • unique_folder1
    • company2
      • unique_folder1
    • ...

rsyncがこれに非常に適していることは知っています。成功せずに「含める/除外する」オプションを試しました。

例えば。私はもう試した:

rsync -avzn --list-only --include '*/unique_folder1/**' --exclude '*' -e ssh [email protected]:/path/to/old/data/ /path/to/new/data/

しかし、結果として、ファイル/ディレクトリは表示されません。

receiving file list ... done
sent 43 bytes  received 21 bytes  42.67 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

どうしましたか?アイデア?


追加情報:両方のサーバーへのSudoアクセスがあります。私が持っているアイデアの1つは、findコマンドとcpioを一緒に使用して、必要なコンテンツを含む新しいディレクトリにコピーし、その後Rsyncを使用することです。しかし、これは非常に遅く、多くのファイルなどがあります。

30
Andron

その理由を見つけました。私に関しては、Rsyncがこのように機能することは明らかではありませんでした。
だから正しいコマンド(company1ディレクトリのみ)は以下でなければなりません:

rsync -avzn --list-only --include 'company1/' --include 'company1/unique_folder1/***' --exclude '*' -e ssh [email protected]:/path/to/old/data/ /path/to/new/data

つまり各親companyディレクトリを含める必要があります。そしてもちろん、これらすべてのcompanyディレクトリをコマンドラインで手動で書き込むことはできないため、リストをファイルに保存して使用します。


最後にすべきこと:

1.サーバー1でインクルードファイルを生成します。そのため、そのコンテンツは次のようになります(lsawkを使用しました)。

+ company1/  
+ company1/unique_folder1/***  
...  
+ companyN/  
+ companyN/unique_folder1/***  

2. include.txtをサーバー2にコピーし、次のコマンドを使用します。

rsync -avzn                                        \
      --list-only                                  \
      --include-from '/path/to/new/include.txt'    \
      --exclude '*'                                \
      -e ssh [email protected]:/path/to/old/data/    \
      /path/to/new/data
28
Andron

最初に一致するパターンがディレクトリを除外する場合、そのすべての子孫は走査されません。深いディレクトリを含める場合(例: company*/unique_folder1/**ただし、他のすべてを除外*、先祖もすべて含めるようにrsyncに指示する必要があります。

rsync -r -v --dry-run                       \
    --include='/'                           \
    --include='/company*/'                  \
    --include='/company*/unique_folder1/'   \
    --include='/company*/unique_folder1/**' \
    --exclude='*'

Bashのブレース展開を使用して、入力を節約できます。中括弧の展開後、次のコマンドは前のコマンドとまったく同じです。

rsync -r -v --dry-run --include=/{,'company*/'{,unique_folder1/{,'**'}}} --exclude='*'
16
yonran

たとえば、_target/classes/_と_target/lib/_のみをリモートシステムに同期する場合は、次のようにします。

_rsync -vaH --delete --delete-excluded --include='classes/***' --include='lib/***' \
      --exclude='*' target/ user@Host:/deploy/path/
_

見るべき重要なもの:

  • パスの末尾の「_/_」を忘れないでください。そうしないと、サブディレクトリにコピーが作成されます。
  • _--include_、_--exclude_の順序がカウントされます。
  • 「_/_」で始まる他の回答に反して、包含/除外パラメーターは不要であり、ソースディレクトリに自動的に追加されます(例では_target/_)。
  • 正確に何が起こるかをテストするために、他の答えが示すように、_--dry-run_フラグを使用できます。
  • _--delete-excluded_ ターゲットディレクトリ内のすべてのコンテンツを削除します。ただし、具体的に含めたサブディレクトリは除きます。賢明に使用する必要があります!このため、_--delete_は十分ではありません。デフォルトではリモート側の除外ファイルを削除しません(他のすべて、はい)。通常の_--delete_の横に再度指定する必要があります。
1
peterh