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


9

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

$ cat DirectoriesToCopy.txt

/data/Dir1
/data/Dir2

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

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

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

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


あなたが転送したいですか/data/Dir1/data/Dir2にその内容を含む/media/MyDestination/Dir1/media/MyDestination/Dir2?または、/dataパーツを含めますか?このリストの大きさは、コマンドラインでこれらのエントリを単純にリストするには大きすぎますか?とにかく、--excludeステートメントは再帰を防ぎます。
ヴルテル2014

これらのディレクトリ内のすべてのファイルも転送したいと思います。そのディレクトリには多くのファイルがあるので、すべてのファイル名を含む別のテキストファイルを作成しないようにします。
indiajoe 2014

のように完全なパスを維持したいと思い/media/MyDestination/data/Dir2/ます。/ excludeを追加して、/内の他のディレクトリやファイルがコピーされないようにしました。
indiajoe 14

ディレクトリのリストがそれほど大きくない場合は、次のオプションの方が簡単だと思いますrsync -av $(cat DirectotiesToCopy.txt) /media/MyDestination/
indiajoe

回答:


6

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

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ではなく、同じことを行う複数の方法を提供するだけです。含める/方法がより適しているかもしれ除外を行くいくつかのケースでは、ここで私は(なし上記--relative事やると思い--relativeますが、で終わるだろう/media/MyDestination/Dir1/media/MyDestination/Dir2し、--relative全体のソースパスが宛先にコピーされます)。


お疲れ様でした。rsyncを使用してディレクトリのリストを単純にコピーするために、このような慎重な一連のフィルターを定義する必要があることに少し驚いています。たとえば、ディレクトリのリストが1つの共通ディレクトリ/ data /の下になく、代わりに多くの場所に分散している場合、定義するフィルターは非常に複雑になります。
indiajoe 2014

私の回答の編集内容をご覧ください。
wurtel

ありがとう。したがって、ディレクトリのリストがそれほど大きくない場合は、以下に示すように--relativeフラグを使用できます。rsync -av --relative $(cat DirectotiesToCopy.txt) /media/MyDestination/
indiajoe 2014

はい; 覚えておいてください--relative
ヴルテル2014

7

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

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

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

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

  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内のファイルは相対ファイルであるか、最上位ディレクトリにある必要があります)

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


1
これは私が必要なものです!ただし、「-include-from」は「--files-from」である必要があります。また、「-list-only」を使用して、RSYNCが実際に機能する前に、RSYNCが何を行うかをプレビューしました。
アダムビーン2017

1
おかげで、私は答えを更新しました。--include-fromも機能しますが、私が言ったこと-rはほとんど関係ありません。
Otheus 2017

2

rsyncのマニュアルは、このシナリオ(節「/パターンルールを除外含める」)について警告します:

これは動作しません:

+ /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/

ルールファイルを作成するための詳細な説明とスクリプトに感謝します。問題を理解しました。rsyncが--dirs-from = DirectoriesToCopy.txtのようなオプションをすべての複雑なフィルターへのショートカットとして持つことができればそれでもいいと思います。
indiajoe 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.