Wie vergleichst du zwei Ordner und kopierst die Differenz in einen dritten Ordner?

23

Sie haben drei Ordner:

  • Ordner aktuell , der Ihre aktuellen Dateien enthält
  • Ordner alt , der eine ältere Version derselben Dateien enthält
  • Ordner Unterschied , der nur ein leerer Ordner ist

Wie kann man vergleichen alt mit aktuellen und kopieren Sie die Dateien , die unterschiedlich sind (oder ganz neu) in Strom zu Unterschied ?


Ich habe überall gesucht und es scheint eine einfache Sache zu sein, aber ich kann es in meinem Beispiel nicht zum Laufen bringen. Die meisten Quellen schlugen die Verwendung von rsync vor, so dass ich den folgenden Befehl erhielt:

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

Das bedeutet jedoch, dass alle Dateien von neu nach unterschiedlich kopiert werden , auch diejenigen, die mit denen in alt identisch sind .

Falls es hilft (vielleicht ist der Befehl in Ordnung und der Fehler liegt woanders), so habe ich das getestet:

  1. Ich habe die drei Ordner gemacht.
  2. Ich habe mehrere Textdateien mit unterschiedlichen Inhalten in alten .
  3. Ich habe die Dateien von alt nach neu kopiert .
  4. Ich habe den Inhalt einiger Dateien in new geändert und ein paar zusätzliche Dateien hinzugefügt.
  5. Ich habe den obigen Befehl ausgeführt und die Ergebnisse auf Unterschiede überprüft .

Ich habe in den letzten Tagen nach einer Lösung gesucht und würde mich sehr über Hilfe freuen. Es muss nicht unbedingt rsync sein, aber ich würde gerne wissen, was ich falsch mache, wenn möglich.

Thane
quelle
mögliches Duplikat von Wie speichere ich geänderte Dateien?
Wingedsubmariner
@wingedsubmariner Ich glaube nicht, dass es sich um ein Duplikat handelt, da die akzeptierte Antwort auf die verknüpfte Frage der Befehl ist, zu dem das OP eine Frage stellt.
Bernhard
@Bernhard Ah, mein böser. Ich glaube, ich habe die ursprüngliche Frage falsch verstanden.
Wingedsubmariner
@wingedsubmariner Keine Sorge, Sie sagten "möglich", und ich stimme zu, es sieht sehr ähnlich :)
Bernhard

Antworten:

7

Ich bin nicht sicher, ob Sie es mit vorhandenen Linux-Befehlen wie rsync oder diff tun können. Aber in meinem Fall musste ich mein eigenes Skript mit Python schreiben, da Python das Modul "filecmp" für den Dateivergleich hat. Ich habe das gesamte Skript und die Verwendung auf meiner persönlichen Website veröffentlicht - http://linuxfreelancer.com/

Die Verwendung ist einfach - geben Sie den absoluten Pfad des neuen Verzeichnisses, des alten Verzeichnisses und des Differenzverzeichnisses in dieser Reihenfolge an.

#!/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()
Daniel t.
quelle
21

Ich habe herausgefunden, was das Problem in meinem Fall war:

Die Dateien, die ich verglichen habe, hatten unterschiedliche Zeitstempel. Ich hätte das Argument -a nicht verwenden sollen , da rsync versucht hat, die Zeitstempel beim Kopieren von Dateien beizubehalten. Der Befehl, der für mich arbeitete, war:

rsync -rvcm --compare-dest=../old/ new/ difference/
Thane
quelle
Ich denke, um dies mit der Option -a (Archiv) zu testen, sollten Sie verwendet haben, rsync -aum die Dateien anfangs "zu kopieren" (oder das CP-Äquivalent), dann zu löschen oder zu ändern. (Ich bleibe gerne bei rsync, weil ich weiß, dass es selbstkonsistent ist, ohne darüber nachzudenken, was es tun könnte.) Ich denke, das hätte mit dem ursprünglichen Befehl funktionieren sollen. Die Option -a enthält -t (Vergleich nach Zeitstempel), die Alternative zu -c (Vergleich nach Prüfsumme).
Salbei
2
Meiner Meinung nach sollte diese Antwort akzeptiert werden, da sie viel einfacher ist. Außerdem hat der Befehl nur bei mir funktioniert, wenn ich den vollständigen Pfad für old/und angegeben habe new/.
Yamaneko
Der Vorbehalt scheint zu sein, dass das Vergleichsziel der relative Pfad zum Unterschied sein muss, wie aus dem tatsächlichen Ziel heraus gesehen
Ryan Williams
1

Dies könnte einigen Lesern helfen: In Windows macht ein älteres, kleines Freeware-Programm - Third Dir - genau das, was hier verlangt wird. Es ist nicht mehr über den Entwickler Robert Vašíček erhältlich. Aber ich bin sicher, dass es über einige Online-Repositories zu finden ist.

Hier ist die Beschreibung des Entwicklers, die auf seiner Website verbleibt:

Drittes Verzeichnis: Ein ungewöhnlicher Verzeichnissynchronisierer - die verschiedenen Dateien werden in das dritte Verzeichnis kopiert. Es ist sehr nützlich, z. B. neue oder bearbeitete Fotos aus einem riesigen Verzeichnisbaum auf der Festplatte in einen temporären Ordner zu extrahieren und sie dann zur Archiv-CD hinzuzufügen (Hinweis: Die Originaldateien werden mit der CD verglichen). Version 1.4, Größe 23kB. Erstellt am 2005-02-12.

Verlauf: Version 1.14 - Effizienter, wenn mehrere Zehntausend Dateien verglichen werden.

Steve
quelle
0

Die von Thane mit Yamaneko-Zusätzen angegebene rsync-Methode funktioniert hervorragend, lässt jedoch leere Verzeichnisse. Für mich bestand die endgültige Lösung aus zwei Schritten: Rufen Sie zuerst rsync mit vollem Pfad auf und dann den Befehl find, um alle leeren Verzeichnisse zu entfernen:

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

Bitte beachten Sie, dass rsync selbst mit der Option --links keine symbolischen Links gespeichert hat, sondern stattdessen die Zieldaten kopiert hat.

PierreL
quelle
Beachten Sie, dass Sie anstelle von verwenden -empty -exec rmdir {} \;können -empty -delete.
2.
-3

Ich benutze den Dualpane XY Explorer (kommerziell), der viele Tricks ausführen kann, und dies ist einer davon. Öffnen Sie Currentin einem Bereich und Alt in dem anderen. Aktivieren Sie den aktuellen Bereich. Gehen Sie zu Fenster > Synchronisierungsauswahl . Es gibt Ihnen 5 Optionen zur Auswahl:

  1. Übereinstimmungen (in beiden aufgelistet)
  2. Einzigartig (im aktiven Bereich)
  3. Neuere (im aktiven Bereich)
  4. Einzigartige und neuere Dateien (im aktiven Bereich)
  5. Ausgewählt (diejenigen, die im anderen Bereich ausgewählt wurden)

Jetzt können Sie die resultierende Auswahl Currentan die gewünschte Stelle kopieren . Ich habe es verwendet, um mailfoldersalte Installationen mit den neuesten zu vergleichen . Die Ordnerstruktur war recht komplex, aber (fast) alle mbs-fileshatten eine eindeutige Nummer.

Also habe ich mbs-filesim alten Stammverzeichnis mailfolder(in einem Bereich) und im neuesten (im anderen Bereich) gesucht und die Suchergebnisse in jedem Bereich verglichen (" Eindeutige Synchronisierung auswählen") , um Mails zu finden, die während des Suchvorgangs fehlten neu installiert)! Sie können auch viele Optionen einstellen.

Martijn Douwes
quelle
1
Wenn Sie über nicht standardmäßige Software sprechen, sollten Sie einen Link hinzufügen. Wenn Sie XYplorer meinen , hilft das dem OP überhaupt nicht.
Anthon