Binärer Dateivergleich per Batchprogramm von Verzeichnisbäumen mit FC - wie, was ist zu beachten ?
Nach einem Systemabsturz scheint auch die Datenpartition Schäden davon getragen zu haben. Auf unterschiedlichen Wegen habe ich Sicherungen der Datenpartition auf anderen Festplatten gemacht (Kopieren im Windows, mit Utility vom Festplattenhersteller die gesamte Partition kopiert und mit einem Recovery-Programm) --> 3 Partitionen deren Inhalt identisch sein sollte. Ist er aber nicht - unterschiedliche Gesamtgröße und Dateizahl. --> nicht alle Dateien sind in allen drei Kopien vorhanden.
Nun möchte ich die Dateien miteinander binär vergleichen, da ich bereits eine Datei gefunden habe (ein Bild) das in der Vorschau anscheinend richtig angezeigt wird, beim Bearbeiten stellt sich aber heraus, daß etwas mit diesem Bild nicht stimmt. In einer anderen der 3 Kopien kann das Bild problemlos bearbeitet werden.
Einige der Daten habe ich auf einer USB-PLatte aber leider nicht alle.
Asche auf mein Haupt, daß ich mich nicht konsequenter um die Sicherung der Daten bemüht habe.
Technische Daten:
Betriebssystem: Win XP Home mit SP2
Dateianzahl: ca. 12.000
Dateigröße: wenige Byte bis ca. 9 GB (AVI-DV-Datei)
Anzahl Verzeichnisse: viele
Namen Dateien und Verzeichnisse: mit Leerzeichen, äöüÄÖÜ', alles was lt. Windows XP zulässig ist.
Meine Vorstellung zur Problemlösung:
Mit
In der Datei stehen dann Zeilen wie:
Zur Prüfung stelle ich mir eine Batch-Datei mit Schleife vor, in der die Einträge der obigen Liste abgearbeitet werden, in z.B. folgender Art:
"%%j" soll die Pfadangabe und den Dateinamen, jedoch ohne Laufwerksangabe enthalten.
Umleitung der Ausgabe nach Null (Nirvana), da bei Unterschieden in den Dateien die Ausgabe der Unterschiede nicht weiter interessiert.
Ausgabe in zwei Dateien, daß einerseits eine Kompakte Darstellung erreicht wird (Fehler.txt) und andererseits ein Log-Datei protokolliert, welche Dateien berücksichtigt wurden (Ergebnis.txt).
Der Anfang mit
Leider gibt es aber auch folgendes
Auch das mit der Umleitung nach NULL und der Auswertung des ERRORLEVELS funktioniert nicht wie ich mir das vorstelle.
Was ist hierbei zu beachten ?
Welche Errorlevel gibt es bei Filecompare FC und wofür stehen sie ?
Darf die FOR-Schleife aus mehreren Zeilen bestehen ?
Ein NEXT %%i scheint es nicht zu geben. Woran wird das Ende der FOR-Schleife erkannt ?
Ist eine FOR-Schleife hier überhaupt das richtige ?
Wie sind die Variablen aus der Datei dir_d.txt zu übergeben, daß bei der Übergabe die Leer- und Sonderzeichen im Pfad- und Dateinamen richtig verarbeitet werden, ...
Wie können die Zeilen ohne Dateiname am Ende aus der "dir_d.txt" eleminiert werden ?
Es gibt sicher weitere Fallstricke wie nach der Lektüre einiger anderer Beiträge vermute.
Bitte helft mir weiter.
Vielen Dank für die Hilfen.
Gruß Michel
Nun möchte ich die Dateien miteinander binär vergleichen, da ich bereits eine Datei gefunden habe (ein Bild) das in der Vorschau anscheinend richtig angezeigt wird, beim Bearbeiten stellt sich aber heraus, daß etwas mit diesem Bild nicht stimmt. In einer anderen der 3 Kopien kann das Bild problemlos bearbeitet werden.
Einige der Daten habe ich auf einer USB-PLatte aber leider nicht alle.
Asche auf mein Haupt, daß ich mich nicht konsequenter um die Sicherung der Daten bemüht habe.
Technische Daten:
Betriebssystem: Win XP Home mit SP2
Dateianzahl: ca. 12.000
Dateigröße: wenige Byte bis ca. 9 GB (AVI-DV-Datei)
Anzahl Verzeichnisse: viele
Namen Dateien und Verzeichnisse: mit Leerzeichen, äöüÄÖÜ', alles was lt. Windows XP zulässig ist.
Meine Vorstellung zur Problemlösung:
Mit
dir d:\ /S /B > dir_d.txt
Liste mit allen Dateien erzeugen.In der Datei stehen dann Zeilen wie:
d:\temp
d:\tmp
d:\temp\img_1234.tif
d:\tmp\capture_1.avi
Leider stehen in der Datei aber auch die Verzeichnisse und ich kann nicht ausschließen, daß es Punkte im Ordnernamen gibt. Es könnte außerdem auch Dateien ohne Erweiterung geben. Wie können die reinen Pfadangaben aus diesr Liste aussortiert werden, da sie beim Filecompare nur unnötige Fehlermeldungen produzieren (s.u.).d:\tmp
d:\temp\img_1234.tif
d:\tmp\capture_1.avi
Zur Prüfung stelle ich mir eine Batch-Datei mit Schleife vor, in der die Einträge der obigen Liste abgearbeitet werden, in z.B. folgender Art:
FOR /F "delims=: tokens=1,2" %%i IN (dir_d.txt)
DO
FC / b d:\%%j e:\%%j > NULL
IF ERRORLEVEL "für Dateien sind identisch" @echo identisch %%j >> Ergebnis.txt
IF ERRORLEVEL "für Dateien sind unterschiedlich bzw. nicht vorhanden" @echo Fehler %%j >> Ergebnis.txt
IF ERRORLEVEL "für Dateien sind unterschiedlich bzw. nicht vorhanden" @echo Fehler %%j >> Fehler.txt
Ende der FOR-Schleife
DO
FC / b d:\%%j e:\%%j > NULL
IF ERRORLEVEL "für Dateien sind identisch" @echo identisch %%j >> Ergebnis.txt
IF ERRORLEVEL "für Dateien sind unterschiedlich bzw. nicht vorhanden" @echo Fehler %%j >> Ergebnis.txt
IF ERRORLEVEL "für Dateien sind unterschiedlich bzw. nicht vorhanden" @echo Fehler %%j >> Fehler.txt
Ende der FOR-Schleife
"%%j" soll die Pfadangabe und den Dateinamen, jedoch ohne Laufwerksangabe enthalten.
Umleitung der Ausgabe nach Null (Nirvana), da bei Unterschieden in den Dateien die Ausgabe der Unterschiede nicht weiter interessiert.
Ausgabe in zwei Dateien, daß einerseits eine Kompakte Darstellung erreicht wird (Fehler.txt) und andererseits ein Log-Datei protokolliert, welche Dateien berücksichtigt wurden (Ergebnis.txt).
Der Anfang mit
FOR /F "delims=: tokens=1,2" %%i IN (dir_d.txt) DO @echo FC / b d:\%%j e:\%%j
liefert den Befehlsaufruf, und der sieht auf den ersten Blick auch gut aus.Leider gibt es aber auch folgendes
FC /b d:\temp e:\temp
Wie zu erkennen ist, fehlen die Dateien am Ende der Pfadangabe, da in der Datei "dir_d.txt" auch solche Zeilen enthalten sind - für jedes Verzeichnis eine - leider (s.o.).Auch das mit der Umleitung nach NULL und der Auswertung des ERRORLEVELS funktioniert nicht wie ich mir das vorstelle.
Was ist hierbei zu beachten ?
Welche Errorlevel gibt es bei Filecompare FC und wofür stehen sie ?
Darf die FOR-Schleife aus mehreren Zeilen bestehen ?
Ein NEXT %%i scheint es nicht zu geben. Woran wird das Ende der FOR-Schleife erkannt ?
Ist eine FOR-Schleife hier überhaupt das richtige ?
Wie sind die Variablen aus der Datei dir_d.txt zu übergeben, daß bei der Übergabe die Leer- und Sonderzeichen im Pfad- und Dateinamen richtig verarbeitet werden, ...
Wie können die Zeilen ohne Dateiname am Ende aus der "dir_d.txt" eleminiert werden ?
Es gibt sicher weitere Fallstricke wie nach der Lektüre einiger anderer Beiträge vermute.
Bitte helft mir weiter.
Vielen Dank für die Hilfen.
Gruß Michel
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 55534
Url: https://administrator.de/contentid/55534
Ausgedruckt am: 20.11.2024 um 02:11 Uhr
8 Kommentare
Neuester Kommentar
Hallo michel123 und willkommen im Forum!
Um Verzeichnisse auszuschließen kannst Du den "dir"-Befehl um den Schalter "/a-d" ergänzen.
Die Schleife könntest Du wie folgt aufbauen:
Kurze Erklärung:
Der Ordnung halber habe ich der Dateiliste und den Protokolldateien einen Pfad (im Beispiel "C:\") zugeordnet.
Durch den Unterprogrammaufruf zur Verarbeitung der einzelnen Dateien kannst Du nicht nur mehrere Befehlszeilen verwenden, sondern auch sehr flexibel die Verarbeitung steuern - das "goto :eof" entspricht einem "Return".
Das Unterprogramm ist wie eine weitere Batchdatei zu betrachten, daher werden auch die übergebenen Parameter mit %1, %2, etc nummeriert. Übergeben werden die Dateinamen mit einschließenden Anführungszeichen, damit enthaltene Leerstellen keine Probleme verursachen.
Die Sonderzeichen sollten unproblematisch sein, da die Dateiliste ja ebenfalls aus der CMD-Shell erstellt und daher die gleiche Codepage (vermutlich 850) verwendet wird.
Die Schreibweise %~1 entfernt beim übergebenen Dateinamen die Anführungszeichen wieder.
Anmerkung: Durch die Verwendung des Delimiters ":" beginnen die Dateinamen/-pfade jeweils mit einem "\" - wenn's stören sollte, könnte alternativ unter Verwendung einer dazwíschengeschalteten Variable einfach der Name/Pfad ab dem 4. Zeichen (also hinter "D:\" beginnend) verwendet werden.
Grüße
bastla
Um Verzeichnisse auszuschließen kannst Du den "dir"-Befehl um den Schalter "/a-d" ergänzen.
Die Schleife könntest Du wie folgt aufbauen:
@echo off & setlocal
if exist C:\Ergebnis.txt del C:\Ergebnis.txt
if exist C:\Fehler.txt del C:\Fehler.txt
for /f "tokens=1* delims=:" %%i in (C:\dir_d.txt) do call :ProcessFile "%%j"
goto :eof
:ProcessFile
if not exist "d:%~1" goto :Fehler
if not exist "e:%~1" goto :Fehler
fc /b "d:%~1" "e:%~1" >nul || goto :Fehler
echo identisch %~1>>C:\Ergebnis.txt
goto :eof
:Fehler
echo Fehler %~1>>C:\Ergebnis.txt
echo Fehler %~1>>C:\Fehler.txt
goto :eof
Der Ordnung halber habe ich der Dateiliste und den Protokolldateien einen Pfad (im Beispiel "C:\") zugeordnet.
Durch den Unterprogrammaufruf zur Verarbeitung der einzelnen Dateien kannst Du nicht nur mehrere Befehlszeilen verwenden, sondern auch sehr flexibel die Verarbeitung steuern - das "goto :eof" entspricht einem "Return".
Das Unterprogramm ist wie eine weitere Batchdatei zu betrachten, daher werden auch die übergebenen Parameter mit %1, %2, etc nummeriert. Übergeben werden die Dateinamen mit einschließenden Anführungszeichen, damit enthaltene Leerstellen keine Probleme verursachen.
Die Sonderzeichen sollten unproblematisch sein, da die Dateiliste ja ebenfalls aus der CMD-Shell erstellt und daher die gleiche Codepage (vermutlich 850) verwendet wird.
Die Schreibweise %~1 entfernt beim übergebenen Dateinamen die Anführungszeichen wieder.
Anmerkung: Durch die Verwendung des Delimiters ":" beginnen die Dateinamen/-pfade jeweils mit einem "\" - wenn's stören sollte, könnte alternativ unter Verwendung einer dazwíschengeschalteten Variable einfach der Name/Pfad ab dem 4. Zeichen (also hinter "D:\" beginnend) verwendet werden.
Grüße
bastla
Moin michel123,
willkommen im Forum.
Na, so weit wollen es aber nicht kommen lassen...
Gruss
Biber
willkommen im Forum.
Die Dateien mit Anführungszeichen im Namen habe ich aus der Liste entfernt.
Na, so weit wollen es aber nicht kommen lassen...
<u>Streiche:</u> for /f "tokens=1* delims=:" %%i in (C:\dir_d.txt) do call :ProcessFile "%%j"
<u>Setze:</u> for /f "delims=" %%i in (C:\dir_d.txt) do call :ProcessFile "%%~pnxi"
Biber
Moin michel123,
ich hoffe, Du hast im Osterurlaub Aufregenderes erlebt als einen binären Dateivergleich per Batch.
Wie ich für mich aussieht, könnten wir den Beitrag auf "Gelöst" und "Geschlossen" setzen, oder?
Denn grundsätzlich scheint es ja zu laufen.
Und wenn es eine einmalig notwendige Aktion war, dann lohnt es sich sicherlich kaum, die oben mit einer Handvoll Batchzeilen zusammengekitteten FC-Aufrufe aus Performance-Gründen komplett in irgendeiner Hochsprache nachzubilden.
Bei dem Versuch könnte ja der nächste Osterurlaub draufgehen...*gg
Grüsse
Biber
ich hoffe, Du hast im Osterurlaub Aufregenderes erlebt als einen binären Dateivergleich per Batch.
Wie ich für mich aussieht, könnten wir den Beitrag auf "Gelöst" und "Geschlossen" setzen, oder?
Denn grundsätzlich scheint es ja zu laufen.
Und wenn es eine einmalig notwendige Aktion war, dann lohnt es sich sicherlich kaum, die oben mit einer Handvoll Batchzeilen zusammengekitteten FC-Aufrufe aus Performance-Gründen komplett in irgendeiner Hochsprache nachzubilden.
Bei dem Versuch könnte ja der nächste Osterurlaub draufgehen...*gg
Grüsse
Biber
Moin michel123,
im Prinzip teilen sich Beitragsersteller und der Mod des Unterforums diese (angenehme) Aufgabe.
Ein angemeldeter/eingeloggter Fragesteller kann direkt unter der Eröffnungsfrage den Button "Editieren" anklicken.
Im Folgefenster sind dann einige Kontrollkästchen anwählbar, unter anderem "Dieser Beitrag gilt als gelöst".
Damit erzeugst Du diesen hübschen grünen Erledigt-Haken.
Danach wird/sollte dann der zuständige Mod diesen Beitrag schließen.
(Der Mod hat dann ein oder zwei Kontrollkästchen mehr, z.B.
"Dieser Beitrag ist geschlossen und kann nicht mehr beantwortet werden.")
Und dieses Schließen eines Beitrags ist (mir) deshalb so wichtig, weil sonst Jahre später irgendeine Schafsnase einen Kommentar druntersemmelt beginnend mit "ich hab genau dasselbe problem, abba mein Drucker schmiert dabei immer so..."
Und diese Menschen sollen dann lieber einen neuen Beitrag aufmachen.
So, back to thread.... ich lass Dir dann mal den Vortritt, damit Du es ausprobieren kannst.
Schönen Abend
Biber
im Prinzip teilen sich Beitragsersteller und der Mod des Unterforums diese (angenehme) Aufgabe.
Ein angemeldeter/eingeloggter Fragesteller kann direkt unter der Eröffnungsfrage den Button "Editieren" anklicken.
Im Folgefenster sind dann einige Kontrollkästchen anwählbar, unter anderem "Dieser Beitrag gilt als gelöst".
Damit erzeugst Du diesen hübschen grünen Erledigt-Haken.
Danach wird/sollte dann der zuständige Mod diesen Beitrag schließen.
(Der Mod hat dann ein oder zwei Kontrollkästchen mehr, z.B.
"Dieser Beitrag ist geschlossen und kann nicht mehr beantwortet werden.")
Und dieses Schließen eines Beitrags ist (mir) deshalb so wichtig, weil sonst Jahre später irgendeine Schafsnase einen Kommentar druntersemmelt beginnend mit "ich hab genau dasselbe problem, abba mein Drucker schmiert dabei immer so..."
Und diese Menschen sollen dann lieber einen neuen Beitrag aufmachen.
So, back to thread.... ich lass Dir dann mal den Vortritt, damit Du es ausprobieren kannst.
Schönen Abend
Biber