2つのフォルダーを比較し、その違いを3番目のフォルダーにコピーするにはどうすればよいですか?


23

次の3つのフォルダーがあります。

  • 現在のフォルダーには、現在のファイルが含まれています
  • 同じファイルの古いバージョンを含むフォルダold
  • フォルダーの違い、これは単なる空のフォルダーです

どのように比較するか、古い現在とで異なる(あるいは全く新しい)しているファイルをコピー電流を違い


私はあらゆるところを検索しましたが、取り組むのは簡単なように思えますが、特定の例ではうまくいきません。ほとんどのソースはrsyncの使用を提案しているので、私は次のコマンドになりました。

rsync -ac --compare-dest=../old/ new/ difference/

ただし、これにより、すべてのファイルがnewからdifferenceにコピーされます(oldと同じファイルであっても)。

それが役立つ場合(コマンドが正常で、障害が他の場所にある場合)、これは私がこれをテストした方法です:

  1. 3つのフォルダーを作成しました。
  2. 私は中に異なる内容で複数のテキストファイルを作った古いです
  3. ファイルをoldからnewにコピーしました
  4. いくつかのファイルの内容を新規に変更し、いくつかの追加ファイルを追加しました。
  5. 上記のコマンドを実行し、結果の違いを確認しました。

私は過去数日間解決策を探していましたが、私はいくつかの助けを本当に感謝しています。必ずしもrsyncを使用する必要はありませんが、可能であれば、間違っていることを知りたいです。



@wingedsubmarinerリンクされた質問で受け入れられた答えは、OPが質問しているコマンドであるため、重複しているとは思いません。
ベルンハルト

@ベルンハルトああ、私の悪い。私は元の質問を誤解したと思います。
wingedsubmariner

@wingedsubmariner心配ない、あなたは「可能」と言った、そして私はそれが非常によく似ていることに同意する:)
ベルンハルト

回答:


7

rsyncやdiffなどの既存のLinuxコマンドを使用して実行できるかどうかはわかりません。しかし、私の場合、Pythonにはファイル比較用の「filecmp」モジュールがあるため、Pythonを使用して独自のスクリプトを作成する必要がありました。スクリプト全体と使用法を個人用サイト-http://linuxfreelancer.com/に投稿しました

使い方は簡単です。新しいディレクトリ、古いディレクトリ、差分ディレクトリの絶対パスをこの順序で指定します。

#!/usr/bin/env python

import os, sys
import filecmp
import re
from distutils import dir_util
import shutil
holderlist=[]

def compareme(dir1, dir2):
    dircomp=filecmp.dircmp(dir1,dir2)
    only_in_one=dircomp.left_only
    diff_in_one=dircomp.diff_files
    dirpath=os.path.abspath(dir1)
    [holderlist.append(os.path.abspath( os.path.join(dir1,x) )) for x in only_in_one]
    [holderlist.append(os.path.abspath( os.path.join(dir1,x) )) for x in diff_in_one]
    if len(dircomp.common_dirs) > 0:
        for item in dircomp.common_dirs:
            compareme(os.path.abspath(os.path.join(dir1,item)), os.path.abspath(os.path.join(dir2,item)))
        return holderlist

def main():
 if len(sys.argv) > 3:
   dir1=sys.argv[1]
   dir2=sys.argv[2]
   dir3=sys.argv[3]
 else:
   print "Usage: ", sys.argv[0], "currentdir olddir difference"
   sys.exit(1)

 if not dir3.endswith('/'): dir3=dir3+'/'

 source_files=compareme(dir1,dir2)
 dir1=os.path.abspath(dir1)
 dir3=os.path.abspath(dir3)
 destination_files=[]
 new_dirs_create=[]
 for item in source_files:
   destination_files.append(re.sub(dir1, dir3, item) )
 for item in destination_files:
  new_dirs_create.append(os.path.split(item)[0])
 for mydir in set(new_dirs_create):
   if not os.path.exists(mydir): os.makedirs(mydir)
#copy pair
 copy_pair=zip(source_files,destination_files)
 for item in copy_pair:
   if os.path.isfile(item[0]):
    shutil.copyfile(item[0], item[1])

if __name__ == '__main__':
 main()

21

私の場合、問題が何であるかがわかりました。

私が比較していたファイルには異なるタイムスタンプがありました。-a引数を使用するべきではありませんでした。ファイルをコピーするときにrsyncがタイムスタンプを保持しようとしていたからです。私のために働いたコマンドは:

rsync -rvcm --compare-dest=../old/ new/ difference/

-a(アーカイブ)オプションを使用rsync -aしてこれをテストすると思います。最初に(またはcpに相当する)ファイルを「コピー」してから削除または変更する必要があります。(rsyncに固執したいのは、それが何をしているのかを考えずに自己整合的であることがわかっているからです。)これは元のコマンドで機能するはずだったと思います。-aオプションには-t(タイムスタンプで比較)が含まれます。これは-c(チェックサムで比較)の代替です。
セージ14

2
私の意見では、この答えははるかに単純なので、受け入れられるべきです。また、old/とに完全なパスを指定した場合にのみ、コマンドが機能しましたnew/
山猫

注意点は、比較先は実際の宛先の内部から見た差分への相対パスでなければならないようです
ライアンウィリアムズ

1

これは一部の読者に役立つかもしれません:Windowsでは、古い小さなフリーウェアプログラム-Third Dir-がここで求められていることを正確に実行します。開発者のRobertVašíčekからは入手できなくなりました。しかし、私はそれがオンラインでいくつかのリポジトリを介して見つけることができると確信しています。

彼のサイトに残っている開発者の説明は次のとおりです。

3番目のディレクトリ:珍しいディレクトリ同期-さまざまなファイルが3番目のディレクトリにコピーされます。たとえば、固定ディスク上の巨大なディレクトリツリーから新規または編集した写真を一時フォルダーに抽出し、それらをアーカイブCDに追加すると非常に便利です(注-元のファイルはCDと比較されます)。バージョン1.4、サイズ23kB。2005-02-12を作成しました。

履歴:バージョン1.14-何万ものファイルを比較する場合により効率的です。


0

Thaneが山猫を追加したrsyncの方法はうまく機能しますが、ディレクトリは空のままです。私にとって最終的な解決策は、2つのステップからなります。最初にフルパスでrsyncを呼び出し、次にすべての空のディレクトリを削除するfindコマンドを呼び出します。

rsync -rvcm --compare-dest=/tmp/org/ /tmp/new/ /tmp/difference/
find /tmp/difference/ -d -type d -empty -exec rmdir {} \; -print

--linksオプションを使用しても、rsyncはシンボリックリンクを保持せず、宛先データをコピーすることに注意してください。


代わりに-empty -exec rmdir {} \;を使用できることに注意してください-empty -delete
mivk

-3

デュアルペインXYエクスプローラー(商用)を使用します。これは多くのトリックを実行できますが、これはその1つです。Current一方のペインで開き、もう一方のペインで古いです。現在のペインをアクティブにします。[ ペイン] > [選択の同期]に移動します。次の5つのオプションを選択できます。

  1. 一致(両方にリストされている)
  2. 一意(アクティブペイン内)
  3. 新しい(アクティブペイン内)
  4. 一意の新しいファイル(アクティブペイン内)
  5. 選択済み(他のペインで選択されているもの)

これで、選択した結果Currentを希望する場所にコピーできます。mailfolders古いインストールと最新のインストールを比較するために使用しました。フォルダ構造は非常に複雑でしたが、(ほぼ)すべてにmbs-files一意の番号がありました。

そこでmbs-files、古いルートmailfolder(一方のペイン)と最新(他方のペイン)で検索を行い、各ペイン(Sync Select Unique)で検索結果を比較して、再インストール)!多くのオプションも設定できます。


1
非標準ソフトウェアについて話している場合は、リンクを含める必要があります。XYplorerを意味する場合は、OPをまったく役に立たないでしょう。
アントン14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.