Verzeichnisse vergleichen

andy_m4

Admiral
Registriert
Aug. 2015
Beiträge
7.743
Liebe Forengemeinde

Ich möchte zwei Verzeichnisse vergleichen. Und zwar rekursiv (inkl. Unterverzeichnisse).
So in der Art von compare /path/to/dir1 /path/to/dir2

Die wesentlichen Informationen die ich raus ziehen möchte sind:
  • welche Dateien aus dir1 kommen auch in dir2 vor (wobei auch berücksichtigt werden soll, wenn die Datei in einem anderen Unterverzeichnis innerhalb von dir2 liegt) und wo die denn da liegen
  • welche Dateien sind nur in dir1
  • welche Dateien sind nur in dir2
Das Kriterium ob eine Datei als gleich anzusehen ist soll sein ob der Inhalt identisch ist (muss kein Bit-für-Bit-Vergleich sein; wenn ne sowas wie ne md5-Prüfsumme gleich ist sollte das reichen).

Die Frage ist jetzt, obs dafür ein geeignetes Tool gibt oder sowas.

Evtl. weiß da ja jemand etwas. :-)
 
Würde mir Beyond Compare und FreeFileSynch ansehen.


Beyond Compare kann es bis auf

andy_m4 schrieb:
welche Dateien aus dir1 kommen auch in dir2 vor (wobei auch berücksichtigt werden soll, wenn die Datei in einem anderen Unterverzeichnis innerhalb von dir2 liegt) und wo die denn da liegen
 
Ich benutze zum Vergleichen von Verzeichnissen das Programm dupeguru Aber damit spüre ich immer nur doppelte Dateien auf. Ich weiß jetzt nicht genau welche Optionen es sonst bietet und ob du damit alles das in Erfahrung bringen kannst was du möchtest.

Es gibt aber auch das Terminal Tool diff das erstaunlich gut ist, wie ich finde. Hab nur noch nicht viel damit gearbeitet, weil ich solche Vergleiche nicht oft machen muss.

https://www.tippscout.de/linux-verzeichnisse-vergleichen_tipp_6141.html
 
  • Gefällt mir
Reaktionen: Linuxfreakgraz
Ohne md5: diff -r foo bar
Mit md5 (auf gnu systemen dann md5sum):
diff <(find foo -type f -exec md5 {} + | sort -k 2 | sed 's/ .\// /') <(find bar -type f -exec md5 {} + | sort -k 2 | sed 's/ .\// /')

Alternativ: git diff foo bar
 
  • Gefällt mir
Reaktionen: gio127 und 0x7c9aa894
Um das hier noch ein bisschen zu ergänzen damit auch ggf. andere Leute Thread profitieren:

Also man kann sowas machen wie
git diff --summary /path/to/dir1 /path/to/dir2

und kriegt dann eine Ausgabe a-la
create mode 100644 /path/to/dir2/subdir/newfile.txt delete mode 100644 /path/to/dir1/myfile.txt rename /path/to/dir1/rezepte.txt => dir2/subdir/kochrezepte.txt} (100%)
usw.

Und dann ist auch klar das wenn etwas delete ist dann ist das ne Datei die in dir1 da ist aber in dir2 nicht mehr bzw. bei create entsprechend umgekehrt. Und rename ist auch klar. Wenn eine Datei umbenannt oder verschoben wurde dann ist auch klar, wohin bzw. wie die jetzt heißt.

Nettes Gimmick ist die "Prozentzahl" dahinter. Die gibt nämlich an, wie groß die Übereinstimmung ist. 100% heißt halt, die Dateien sind tatsächlich identisch. Wenns ne kleinere "Prozentzahl" ist dann ist die halt geringfügig anders (bei Textdateien wenn da ein Buchstabe, Wort, etc. anders ist).

Die Ausgabe ist je nachdem wie git die Dateien gerade findet. Wenn man create, delete und rename sortieren möchte, muss man natürlich noch ein sort drüber legen. Außerdem kann es Sinn machen die Ausgabe in eine Datei zu schreiben
git diff --summary /path/to/dir1 /path/to/dir2 | sort >/tmp/log.txt

Bei sehr vielen Dateien kann es eine Meldung a-la
Warnung: genaue Erkennung für Umbenennungen wurde aufgrund zu vieler Dateien übersprungen.
Warnung: Sie könnten die Variable diff.renameLimit auf mindestens 34428 setzen und den Befehl erneut versuchen.
geben.

diff.renameLimit kann man mit dem -l Parameter anpassen:
git diff -l0 --summary /path/to/dir1 /path/to/dir2 | sort >/tmp/log.txt
Wobei 0 halt bedeutet das kein Limit gesetzt ist (siehe dazu auch: https://git-scm.com/docs/git-diff).

Das Schöne an der Lösung ist, das die einfach ist. Man braucht keine komplizierte Shell-Akrobatik mit dutzenden Parametern usw. und sie ist dabei auch noch relativ schnell.
Und hinten fällt ne Textdatei raus, die man dann ggf. computergestützt analysieren und/oder weiterverarbeiten kann.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Beelzebot, Linuxfreakgraz, gio127 und eine weitere Person
Der Klassiker dazu:

Code:
FDUPES(1)                                                General Commands Manual                                               FDUPES(1)

NAME
       fdupes - finds duplicate files in a given set of directories

SYNOPSIS
       fdupes [ options ] DIRECTORY ...

DESCRIPTION
       Searches the given path for duplicate files. Such files are found by comparing file sizes and MD5 signatures, followed by a byte-
       by-byte comparison.

Wobei fdupes ein Fork namens jdupes hat, welcher mit -u auch eine Liste an Dateien ausspucken kann, die einzigartig sind.
Code:
JDUPES(1)                                                General Commands Manual                                               JDUPES(1)

NAME
       jdupes - finds and performs actions upon duplicate files

SYNOPSIS
       jdupes [ options ] DIRECTORIES ...

DESCRIPTION
       Searches  the given path(s) for duplicate files. Such files are found by comparing file sizes, then partial and full file hashes,
       followed by a byte-by-byte comparison. The default behavior with no other "action options" specified  (delete,  summarize,  link,
       dedupe, etc.) is to print sets of matching files.
 
  • Gefällt mir
Reaktionen: gio127 und foo_1337
Ja. fdupes (bzw. jdupes) kenne ich. Macht aber nicht das, was ich suche. Klar kann man das benutzen und sich letztlich damit alle Informationen rauszuziehen. Aber das artet dann ja wieder in Gebastel aus. Da ist dann die git-Lösung schöner.

Wenns nur darum geht Dubletten zu finden macht es das aber recht schnörkellos und effektiv.
 
jdupes -r ./dir1/ ./dir2/
Alle Kollisionen


jdupes -ru ./dir1 ./dir2 | grep '/dir1/'
Alle einzigartigen Dateien aus dir1

Mit minimalen Modifikationen kannst du so all die Anforderungen aus deinem Startpost erfüllen.
 
  • Gefällt mir
Reaktionen: gio127
Zurück
Oben