コマンドラインツールで2つのフォルダーを同期する方法


63

WindowsからLinuxに移行した後、Winmergeの代替ソフトウェアを見つけるか、Linuxの2つのフォルダーを比較および同期するコマンドラインツールを学びたいと思います。コマンドラインで次のタスクを実行する方法を教えていただければ幸いです...(diffとrsyncを勉強しましたが、まだ助けが必要です。)

「/ home / user / A」と「/ home / user / B」の2つのフォルダーがあります

フォルダーAは通常のファイルとフォルダーが保存される場所であり、フォルダーBはフォルダーAの完全なミラーとして機能するバックアップフォルダーです(フォルダーBのユーザーによって直接保存または変更されるものはありません)。

私の質問は:

  • フォルダーBにのみ存在するファイルを一覧表示する方法は?(たとえば、最後の同期以降にフォルダーAから削除されたもの。)

  • フォルダーBにのみ存在するファイルをフォルダーAにコピーする方法

  • 両方のフォルダーに存在するが、タイムスタンプまたはサイズが異なるファイルを一覧表示する方法は?(最後の類義語以降にフォルダーAで変更されたもの。何万ものファイルがあり、プロセスが遅すぎるため、チェックサムの使用を避けたいと思います。)

  • フォルダーAの正確なコピーをフォルダーBに作成する方法は?つまり、フォルダーAからフォルダーAにのみ存在するフォルダーBにすべてをコピーし、フォルダーBにのみ存在するフォルダーBからすべてを削除しますが、両方のフォルダーで同じファイルには触れません。


これに適切なバックアッププログラムを使用してみませんか?重複はその一例です。
クディット

回答:


88

これにより、フォルダーAがフォルダーBに配置されます。

rsync -avu --delete "/home/user/A" "/home/user/B"  

あなたがしたい場合は、フォルダAとBの内容が同じになるように、入れ/home/user/A/源として(スラッシュ)。これは、フォルダーAではなく、そのすべてのコンテンツを取得し、フォルダーBに入れます。このように:

rsync -avu --delete "/home/user/A/" "/home/user/B"
  • -a すべてのファイルシステム属性を保持しながら同期を実行します
  • -v 冗長に走る
  • -u 新しい変更時刻(または、時刻が等しい場合はサイズの違い)を持つファイルのみをコピーします
  • --delete ソースに存在しないターゲットフォルダ内のファイルを削除します

マンページ:https : //download.samba.org/pub/rsync/rsync.html


7
rsync:rsyncの実行アプリ、-a:すべてのファイルシステムの属性を保存同期を行い、-v:冗長に実行し、-z:同期中にデータを圧縮(圧縮モードでデータを転送する)、--delete:ターゲット内のファイルを削除しますソースに存在しないフォルダー、/ home / user / A:ソースフォルダー、/ home / user / B:ターゲットフォルダー
-SonicARG

こんにちは、SonicARG、私は完全にこれに戻って説明をするのを忘れていました。説明を提出してくれてありがとう。
TuxForLife

6
Rsyncは、主に異なるコンピューター間でファイルをコピーすることを目的としています。ここで説明するように、ディレクトリを同期する目的にも役立ちます。したがって、-zオプションは、ネットワークトラフィックを減らし、2台のコンピューター間のrsyncのパフォーマンスを向上させるために興味深いものです:(ディスクからデータを読み取る->圧縮)=== network ===>(uncompress-> write to disk)同じホスト上の2つのディレクトリを同期するzは少し愚かで、CPUサイクルの無駄です(ディスクからデータを読み取る->圧縮->圧縮
解除

@GerritCap、編集しました。貴重なご
意見をありがとうござい

1
コマンドを試しましたが、/home/user/B/AAのコンテンツをBのコンテンツに上書きする代わりにサブディレクトリを作成します。ご覧ください。
ルーク

10

unisonU PennのBenjamin Pierceが開発したツールを使用できます。

2つのディレクトリがあると仮定します。

/home/user/Documents/dirA/ そして /home/user/Documents/dirB/

これら2つを同期するには、次を使用できます。

〜$unison -ui text /home/user/Documents/dirA/ /home/user/Documents/dirB/

出力でunisonは、同期を要求した2つのディレクトリで異なるすべてのディレクトリとファイルが表示されます。その後、あなたのマシン上で同期ツリーを作成し、維持し、最初の実行に(どちらの場所で見つからないファイルを複製する)付加的に同期させることをお勧めします、とあなたはからファイルを削除した場合、その後の実行では、すなわち(真の同期を実装します.../dirA、それ削除されます.../dirB同様。また、一人ひとりの変化を比較し、必要に応じてするかを選択できフォワードまたはリバース二つのディレクトリ間で同期します。

必要に応じて、グラフィカルインターフェイスを起動するには-ui text、コマンドからオプションを削除しますが、cli使用する方が簡単で高速です。

詳細については、UnisonユーザーマニュアルのUnisonチュートリアルを参照してください


1

TuxForLifeからの回答はかなり良いですが、-cローカルで同期するときに使用することを強くお勧めします。リモート同期のために時間/ネットワークのペナルティをする価値はないと主張できますが、速度が非常に速いため、ローカルファイルに対しては完全に価値があります。

-c, --checksum
       This forces the sender to checksum every regular file using a 128-bit  MD4
       checksum.   It  does this during the initial file-system scan as it builds
       the list of all available files. The receiver then checksums  its  version
       of  each  file  (if  it exists and it has the same size as its sender-side
       counterpart) in order to decide which files need to be updated: files with
       either  a  changed  size  or a changed checksum are selected for transfer.
       Since this whole-file checksumming of all files on both sides of the  con-
       nection  occurs  in  addition to the automatic checksum verifications that
       occur during a file's transfer, this option can be quite slow.

       Note that rsync always verifies that each transferred file  was  correctly
       reconstructed  on  the receiving side by checking its whole-file checksum,
       but that automatic after-the-transfer verification has nothing to do  with
       this  option's  before-the-transfer  "Does  this file need to be updated?"
       check.

これは、同じサイズとタイムスタンプを使用すると失敗する可能性があることを示しています。

セットアップ

$ cd /tmp

$ mkdir -p {A,b}/1/2/{3,4}

$ echo "\___________from A" | \
      tee A/1/2/x  | tee A/1/2/3/y  | tee A/1/2/4/z  | \
  tr A b | \
      tee b/1/2/x  | tee b/1/2/3/y  | tee b/1/2/4/z  | \
      tee b/1/2/x0 | tee b/1/2/3/y0 >     b/1/2/4/z0

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from b
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from b
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from b
b/1/2/x0
\___________from b

ファイルのサイズとタイムスタンプがすべて同じであるため、何もコピーしないrsync

$ rsync -avu A/ b
building file list ... done

sent 138 bytes  received 20 bytes  316.00 bytes/sec
total size is 57  speedup is 0.36

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from b
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from b
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from b
b/1/2/x0
\___________from b    

チェックサムを比較するため、正しく機能するrsync

$ rsync -cavu A/ b
building file list ... done
1/2/x
1/2/3/y
1/2/4/z

sent 381 bytes  received 86 bytes  934.00 bytes/sec
total size is 57  speedup is 0.12

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from A
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from A
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from A
b/1/2/x0
\___________from b

-cと-uは一緒に動作しますか?
セルゲイコルジョフ

@SergeyKorzhovします。`-u 'は、宛先が新しくない場合にのみ更新するために通常どおり機能します。
ブルーノブロノスキー

1

これは、個人ファイルのバックアップに使用しているものです。ここでは、でカバーされるすべてのことを気にせず-a、より有用な情報を印刷したいと考えています。

rsync -rtu --delete --info=del,name,stats2 "/home/<user>/<src>/" "/run/media/<user>/<drive>/<dst>"

rsyncのmanページ

-r、--recursive
これは、ディレクトリを再帰的にコピーするようにrsyncに指示します。

-t、-times
これはrsyncに変更時刻をファイルとともに転送し、リモートシステムで更新するように指示します。

-u、-update
これにより、rsyncは、宛先に存在し、ソースファイルよりも変更された時刻を持つファイルをスキップします。(既存の宛先ファイルの変更時間がソースファイルと同じ場合、サイズが異なる場合は更新されます。)

--delete
これは、受信側(送信側にないファイル)から無関係なファイルを削除するようにrsyncに指示しますが、同期されているディレクトリに対してのみです。

--info = FLAGS
このオプションを使用すると、表示する情報出力をきめ細かく制御できます。

から rsync --info=help

DEL        Mention deletions on the receiving side  
NAME       Mention 1) updated file/dir names, 2) unchanged names  
STATS      Mention statistics at end of run (levels 1-3)

明示的ではありませんが、これは一見同等で短く見えます:

rsync -rtuv --delete --info=stats2 "/home/<user>/<src>/" "/run/media/<user>/<drive>/<dst>"

-v、-verbose
単一の-vは、転送されるファイルに関する情報と、最後の要約[stats1]を提供します。


0

これはあなたが求めるものと完全に同じではありませんが、バージョン管理ツールの使用を検討することができます。Gitのようなツールは、必要なすべてを実行します。さらに、特にフォルダーBで直接作業していない場合は、それを見てみると面白いかもしれません。gitの詳細についてはこちらをご覧ください


2
これは、バージョン管理にすべてを追加する場合にのみ機能します。また、これまでコミットされたすべての変更が強制的に永続的に保存されるため、望ましくない場合があります。
クディット

@Qudit、それは本当です。ただし、複製によって履歴を制限することは可能ですが、デフォルトではGitに履歴の制限は実装されていません(まだ?)。
switch87

@ switch87はい、古いコミットを削除できることは知っています。ただし、特に大規模なバイナリファイルがある場合、バージョン管理は一般的なバックアップには実際には適切なソリューションではありません。
クディット

彼の質問はローカルバックアップですが、リモートバックアップに使用する場合でも、大きなファイルにはgit annexを使用できます。ローカルバックアップの場合、これは問題ではありません。
switch87

2
@ switch87これは、バックアップを行うためにgitを使用する方法を説明していないため、これはQに対するコメントであり、答えではありませんでした。
slm

0

次のように使用できます。

rsync -avu --delete /home/user/A/* /home/user/B/

この方法では、フォルダーA自体のコンテンツではなく、フォルダーAのコンテンツをフォルダーBにコピーします。

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