Neue Antwort schreiben 
 
Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Doppelte Datei finden in Ordner/Platte etc.
gandro Offline
Quälgeist

Beiträge: 8.950
Registriert seit: Jul 2008
Beitrag #1
Doppelte Datei finden in Ordner/Platte etc.
Kennt einer für Unix/Linux nen Tool was zwei Dateibäume vergleicht, so dass ich synchronisieren kann, also doppelte Dateien in verschiedenen Pfaden erkennt und mir sagt, welche Dateien nur im einen Baum vorhanden sind?
02.09.2010 21:00
Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
DosAmp Offline
Anderes Zeigegerät

Beiträge: 12.219
Registriert seit: Jul 2008
Beitrag #2
Doppelte Datei finden in Ordner/Platte etc.
gandro schrieb:  Kennt einer für Unix/Linux nen Tool was zwei Dateibäume vergleicht, so dass ich synchronisieren kann, also doppelte Dateien in verschiedenen Pfaden erkennt und mir sagt, welche Dateien nur im einen Baum vorhanden sind?
Und die Bäume waren ursprünglich mal von der Verzeichnisstruktur her synchron (du suchst also eine Funktionalität wie ein vereinfachtes, bidirektionales rsync(1)) oder ist ihre Relation zueinander wie Kraut und Rüben, sodass man sich nicht auf Dateinamen, Dateigrößen oder Modifikationszeiten verlassen kann? Im ersteren Fall könnte es genügen, sich aus find(1)(, sort(1)) und comBanana Facepalm1) (gemeinsame oder unikale Zeilen zweier sortierter Dateien ausgeben) fix ein Skript zusammenzukleben, das nur mit den unterschiedlichen Zeilen operiert.

EDIT: Das sähe wohl etwa so aus (hab ich gerade in Notepad++ zusammengebaut, kann nicht für die Funktionalität garantieren):
Code:
pushd $TREE1
find | sed 's/^\.\///' | sort > /tmp/tree1
popd; pushd $TREE2
find | sed 's/^\.\///' | sort > /tmp/tree2
popd
# in TREE2 fehlende Dateien kopieren
comm -23 /tmp/tree1 /tmp/tree2 | \
while read f; do
    f=${f#./}
    # schneller als dirname
    [ -d $TREE2/${f%/*} ] || mkdir -p $TREE2/${f%/*}
    [ -e $TREE2/$f ] || cp $TREE1/$f $TREE2/$f
done
# dasselbe andersrum
comm -13 /tmp/tree1 /tmp/tree2 | \
while read f; do
    f=${f#./}
    [ -d $TREE1/${f%/*} ] || mkdir -p $TREE1/${f%/*}
    [ -e $TREE1/$f ] || cp $TREE2/$f $TREE1/$f
done
rm /tmp/tree1 /tmp/tree2
Auch wenn ich auf einmal dir gar nicht sagen kann, was dieser Schnippsel besser als
Code:
rsync -a --size-only $TREE1/ $TREE2
rsync -a --size-only $TREE2/ $TREE1
erledigen soll.

CCITTグループ4またはZIP圧縮のモノクロ300dpiで最高の再現性
(Dieser Beitrag wurde zuletzt bearbeitet: 02.09.2010 23:48 von DosAmp.)
02.09.2010 23:14
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
gandro Offline
Quälgeist

Beiträge: 8.950
Registriert seit: Jul 2008
Beitrag #3
Doppelte Datei finden in Ordner/Platte etc.
DosAmp schrieb:  
gandro schrieb:  Kennt einer für Unix/Linux nen Tool was zwei Dateibäume vergleicht, so dass ich synchronisieren kann, also doppelte Dateien in verschiedenen Pfaden erkennt und mir sagt, welche Dateien nur im einen Baum vorhanden sind?
Und die Bäume waren ursprünglich mal von der Verzeichnisstruktur her synchron (du suchst also eine Funktionalität wie ein vereinfachtes, bidirektionales rsync(1)) oder ist ihre Relation zueinander wie Kraut und Rüben, sodass man sich nicht auf Dateinamen, Dateigrößen oder Modifikationszeiten verlassen kann? Im ersteren Fall könnte es genügen, sich aus find(1)(, sort(1)) und comBanana Facepalm1) (gemeinsame oder unikale Zeilen zweier sortierter Dateien ausgeben) fix ein Skript zusammenzukleben, das nur mit den unterschiedlichen Zeilen operiert.

EDIT: Das sähe wohl etwa so aus (hab ich gerade in Notepad++ zusammengebaut, kann nicht für die Funktionalität garantieren):
Hm.. werds mir am Abend dann noch mal anschauen, wenn ich Zeit habe. comBanana Facepalm1) hab ich bisher aber nicht in Betracht gezogen - frage mich wie gut das mit Binärdateien auskommt, weil geht in erster Linie um Binärdateien.

Aber ich glaube (angeschaut hab ichs wie gesagt noch nicht genauer) dein Programm hat das gleiche Problem wie rsync (was aber sowieso nur unidirektional ist) oder csync oder unison (beide bidirektional, tun was dein rsync-Zweizeiler tut in einer Zeile) auch:

Sie erkennen gleiche Dateien mit unterschiedlichen Pfaden nicht. Und das will ich schon, sonst hätt ich längst rsync genommen. Hab mir gestern Abend nen Mockup erstellt, wie ich mir die Ausgabe von so nem Programm überhaupt vorstelle (syncen soll das ja vorerst nichtmals, weil die Platten ggf. 100km Luftlinie dazwischen haben):

Code:
# gleiche Datei, unterschiedlicher Pfad
[b]/a/Filme/Kinofilme/Pulp.Fiction.avi     ===     /b/pulp.fiction.avi[/b]

# Ordner fehlt in Baum /b
[b]/a/Musik/Amity in Fame/                 ---     <missing>[/b]

# Datei fehlt in Baum /a
[b]<missing>                               +++     /b/Musik/Tchaikovsky.mp3[/b]

# Unterschiedliche Datei in beiden Bäumen
[b]/a/notes.txt                            !!!     /b/notes.txt[/b]


# gleiche, in beiden Pfaden vorhandene Dateien werden [b][u]nicht[/u][/b] angezeigt.
# ...

Die Anzeige dass der nen kompletten Ordner als fehlend erkennt ist nur optional, im Zweifelsfall soll der nur auf Dateiebene arbeiten.
03.09.2010 11:49
Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
oreissig Offline
Maître Modérateur

Beiträge: 12.021
Registriert seit: Jul 2008
Beitrag #4
Doppelte Datei finden in Ordner/Platte etc.
gleiche dateien in unterschiedlichen pfaden?
hm meine erste idee wäre jetzt von allen files ne prüfsumme erstellen lassen und dann schauen, welche prüfsumme (und die datei dazu) nur in einem davon existiert
hab ich was übersehen, oder ist das das, was du suchst?
03.09.2010 12:10
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
chiaki Offline
Die Pommesfee

Beiträge: 12.554
Registriert seit: Jul 2008
Beitrag #5
Doppelte Datei finden in Ordner/Platte etc.
oreissig schrieb:  gleiche dateien in unterschiedlichen pfaden?
hm meine erste idee wäre jetzt von allen files ne prüfsumme erstellen lassen und dann schauen, welche prüfsumme (und die datei dazu) nur in einem davon existiert
hab ich was übersehen, oder ist das das, was du suchst?

mein kleines bashscript mit sqlite funktioniert auf diese weise ;)
ist nur leider nicht wirklich optimiert, aber der PROOF OF CONCEPT geht
ich überleg ob ich nich daraus ne eigene suchfunktion bastel ohne checksumme, weil dieses ganzen desktop indexierungkram funktioniert nicht wirklich so wie ich will
(Dieser Beitrag wurde zuletzt bearbeitet: 03.09.2010 14:25 von chiaki.)
03.09.2010 14:22
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
gandro Offline
Quälgeist

Beiträge: 8.950
Registriert seit: Jul 2008
Beitrag #6
Doppelte Datei finden in Ordner/Platte etc.
oreissig schrieb:  gleiche dateien in unterschiedlichen pfaden?
hm meine erste idee wäre jetzt von allen files ne prüfsumme erstellen lassen und dann schauen, welche prüfsumme (und die datei dazu) nur in einem davon existiert
hab ich was übersehen, oder ist das das, was du suchst?
Das hast du schon richtig erkannt - wenn ich mir dafür aber nen Script mache, will ich das direkt in richtig, mit "Datenbank", so dass ich bei nem späteren Vergleich nur für neue Dateien nochmals Prüfsumme berechnen muss.
03.09.2010 16:47
Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
oreissig Offline
Maître Modérateur

Beiträge: 12.021
Registriert seit: Jul 2008
Beitrag #7
Doppelte Datei finden in Ordner/Platte etc.
wenn du das mit SQLite machst, könnteste vermutlich auch gleich die Auswertung in die DB verlegen und müsstest nur noch ne kleine output-routine selber proggen
03.09.2010 16:50
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
gandro Offline
Quälgeist

Beiträge: 8.950
Registriert seit: Jul 2008
Beitrag #8
Doppelte Datei finden in Ordner/Platte etc.
Ich hatte mal nen Script in Python angefangen, weil das mit Sets die ganze Vergleichlogik direkt in der Sprache hat. Das Updaten und Speichern des Dateibaums ist die grössere Frage.

An sich stellt sich die Frage ob man ne gewöhnliche Tabelle macht (aka. SQLite oder son Krams) oder mit nem Binärbaum arbeitet (was für die Abfrage ob ein Hash bereits existiert schnell wie Pommes ist, für Abfrage ob Dateipfad schon existiert hingegen weniger).

Nachtrag: Generell ist das Updaten der DB die meisten Gedanken wert, man muss sich überlegen ob man den Dateibaum durchgeht und für jede Datei in der DB nachfragt, oder ob man direkt die DB durchscrollt und überprüft ob sich an der Datei was geändert hat - dann hat man aber das Problem, dass neue Dateien explizit gesucht werden müssen.
03.09.2010 17:00
Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
oreissig Offline
Maître Modérateur

Beiträge: 12.021
Registriert seit: Jul 2008
Beitrag #9
Doppelte Datei finden in Ordner/Platte etc.
die datenbank wird die tabelle ja wohl auch kaum als verkettete liste abspeichern
03.09.2010 17:01
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
chiaki Offline
Die Pommesfee

Beiträge: 12.554
Registriert seit: Jul 2008
Beitrag #10
Doppelte Datei finden in Ordner/Platte etc.
da gandro sowas ja momentan sucht, und es schon vorschläge gibt :)
mach ich maln extra thread draus:

so sieht momentan meine (auf die schnelle gemachte) methode aus:

datenbank erstellen:
sqlite test1.db "create table liste ( name text, hash text, size int)"

checkeuda.sh [Pfad] [Datenbankname]
Code:
#!/bin/bash
#$1 = Pfad
#$2 = Datenbank

find $1 -type f -exec ./sqleuda.sh {} $2 ';'

sqleuda.sh [Datenbank] [Datei]
Code:
#!/bin/bash

HASH=$(md5sum $1| awk '{print $1}')
NAME=$1
SIZE=$(stat -c %s $1)
echo $NAME, $SIZE, $HASH
sqlite $2 "insert into liste (name, hash, size) values ( \"$NAME\", \"$HASH\", \"$SIZE\")"

um die doppelte dateien anzuzeigen (geordnet nach hash) + befehl in xargs (wenn man möchte ):
doppeltdatei.sh [datenbank]
Code:
#!/bin/bash
#$1 datenbankname
sqlite $1 select * from liste INNER JOIN (select *, count(hash) as anzahl from liste group by hash having ( count(hash) > 1)) group by liste.hash;"

# select liste.name from liste INNER JOIN (select *, count(hash) as anzahl from liste group by hash having ( count(hash) > 1)) group by liste.hash;" | xargs -i file {}

checkeuda.sh /home/ test1.db

und dann doppeltdatei.sh test1.db
funktioniert bei mir :)
kann man sicherlich noch verbessern, da es in bash nich gerade das schnellste ist, ausserdem müsste es kein problem sein zwei datenbanken zu vergleichen wenn man den den sqlbefehl etwas verändert (wäre eigentlich sinnvoller ne neue tabelle zu erstellen statt datenbank)
(Dieser Beitrag wurde zuletzt bearbeitet: 03.09.2010 18:10 von chiaki.)
03.09.2010 17:58
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
Neue Antwort schreiben 


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste