web-dev-qa-db-ja.com

rsyncテキストファイルの絶対パスを持つディレクトリのリスト

絶対パスを含むディレクトリのリストを含むテキストファイルがあります。

$ cat DirectoriesToCopy.txt

/data/Dir1
/data/Dir2

Rsyncを使用して、これらのすべてのディレクトリを絶対パスを保持しながら別の場所にコピーしたいと考えています。

次のrsyncコマンドを試しましたが、機能しません

rsync -avr --include-from=DirectoriesToCopy.txt --exclude='*/' --exclude='/*'  /  /media/MyDestination/

ここで何が問題になっていますか?

8
indiajoe

次のコマンドを使用します。

_rsync -av --include-from=DirectoriesToCopy.txt --include /data/ --exclude='/data/*' --exclude='/*/' / /media/MyDestination/
_

/ data /を明示的に含める必要があります。これをファイルのリストに追加することもできます。次に、他のすべてのディレクトリを除外します(includes/excludesでは順序が重要です)。

_-r_に含まれている_-a_の使用は冗長であることに注意してください。

編集:同じ結果を次のようにして達成することもできます:

_rsync -av --relative /data/Dir1 /data/Dir2 /media/MyDestination/
_

いくつかのディレクトリをコピーするだけで困難なことを強いられるのはrsyncではなく、同じことを行う複数の方法を提供するだけです。場合によっては、include/excludeの方が適していることがあります。ここでは、上記の--relativeを実行します(_--relative_を使用しないと、_/media/MyDestination/Dir1_と_/media/MyDestination/Dir2_になります)。 _--relative_を使用すると、ソースパス全体が宛先にコピーされます)。

6
wurtel

Rsyncを使用してこれらのすべてのディレクトリを[リストから]コピーし、その絶対パスを別の場所に保持したい

--includeまたは--filterのバリエーションを使用しないでください。混乱を招くだけです。代わりに、--files-from=_filename_を使用してください。 (行う場合は、必ずlotsのテストを行ってください。)

  1. ファイルにディレクトリリストを作成します。1行に1つのディレクトリ/ファイルを作成します。

  2. 上記のファイルでrsyncの--files-from=を使用します。

  3. --relative/-Rオプションを使用して、ソースパス名が宛先の最後にコピーされるようにします。

  4. -aオプションがある場合でも、-rも含めます。 manページから:

    どちらの場合も、-rオプションが有効になっていると、そのdirの階層全体も転送されます(-aは-aに含まれないため、-files-fromで-rを明示的に指定する必要があることに注意してください)。

完全なコマンド:

rsync ${DEBUG:+-nv} -arR --files-from=<list_of_files.txt> <top-level-dir>  <target-dir>

list_of_files.txtのファイルは相対ファイルであるか、またはtop-level-dirにある必要があります)

(DEBUGが設定されている場合、rsyncはコピーされた可能性のあるものを出力するだけです。)

7
Otheus

rsync manual は、このシナリオについて警告します(「パターンの包含/除外ルール」セクション):

これは動作しません:

+ /some/path/this-file-will-not-be-found
+ /file-is-included
- *

親ディレクトリ"some"'*'ルールによって除外されるため、これは失敗し、rsyncは"some"または"some/path"ディレクトリ内のファイルにアクセスしません。 1つの解決策は、単一のルール"+ */""- *"ルールの前のどこかに置く)を使用して、階層内のすべてのディレクトリを含めるよう要求し、--Prune-empty-dirsオプションを使用することです。別の解決策は、訪問する必要があるすべての親ディレクトリの特定のインクルードルールを追加することです。たとえば、次の一連のルールは適切に機能します。

+ /some/
+ /some/path/
+ /some/path/this-file-is-found
+ /file-also-included
- *

あなたの場合、最も簡単なアプローチは、含めるディレクトリのリストを前処理して、/path/to/fooを含めるたびにすべての親ディレクトリ(/path/to/path/)、および元のディレクトリのサブディレクトリ(/path/to/foo/***)も含めます。これには、以前にリストされていないものすべてを除外するルールがあります(*)。

<DirectoriesToCopy.txt awk '
    {print "+ " $0 "/***"; while (sub(/\/+[^\/]+\/*$/, "/")) print "+ " $0}
    END {print "- *"}
' >rsync-rules.txt
rsync -avr --include-from=rsync-rules.txt  /  /media/MyDestination/