PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : perl: Verzeichnis nach gleichen Dateien durchsuchen



benito
31-03-2003, 17:10
Hi Leute

hab ein Arbeitsproblem:

hab ein Riesenverzeichnis, mit vielen Unterverz. alles .jpg.
Nun will ich eben dieses große Dir (rekursiv) nach gleichen Dateine durchsuchen,
die perfekte Aufgabe für perl, oder? Aber ich komm einfach nicht drauf!
Der Ansat > foreach ($file = readdir DH) < liefert mir nur die Einträge der
Unterverzeichnisse. (1 Hürde)
Was ich auch nicht checke is wie ich mit den Dateitestoperator -s alle Dateien durchleuchte
und eben Dateien mit gleicher Byte-Größe in einem Array sammle?(2. Hürde) Keine Ahnung... das ganze
zum Unglück noch unter Win2000, später dann XP?
Die Sache liegt mir schon länger auf den Magen, darum wär ich wirklich sehr dankbar für Hilfe.
Ich erwarte keine fertigen Lösungen!! Tipps und Schupps bitte! Muß ja selber lernen...
Danke für´s lesen
B.

woodghost
01-04-2003, 08:20
Hab ich in Selfhtml gefunden vielleicht hilft es dir ja.



#!/usr/bin/perl -w

use strict;
use CGI::Carp qw(fatalsToBrowser);

my $Verzeichnis = "/daten/web";
opendir(DIR, $Verzeichnis) || die "$Verzeichnis: $!";
my @Eintraege = readdir(DIR);
closedir(DIR);

print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Testausgabe</title></head><body>\n";
foreach(@Eintraege) {
print "$_<br>\n";
}
print "</body></html>\n";



Erläuterung:


Im Beispiel wird in dem Skalar $Verzeichnis der Pfad eines Verzeichnisses gespeichert ("/daten/web"). Beachten Sie, dass die Verzeichnisse des Pfades durch einfache Schrägstriche getrennt sind, nicht durch Backslashes wie unter DOS/Windows üblich. Verwenden Sie die Syntax mit den einfachen Schrägstrichen auch dann, wenn Perl bei Ihnen unter DOS/Windows läuft. Wenn Sie in einer DOS/Windows-Umgebung ein anderes als das aktuelle Laufwerk ansprechen möchten, setzen Sie einfach den Laufwerksbuchstaben mit Doppelpunkt davor, also beispielsweise c:/temp.


Mit der Funktion opendir wird das Verzeichnis geöffnet. DIR ist ein selbst vergebener Name für das Verzeichnishandle. Ferner bekommt die Funktion den Skalar übergeben, in dem das gewünschte Verzeichnis gespeichert ist. Falls das Verzeichnis nicht geöffnet werden kann, endet das Script durch Aufruf der Funktion die.


Das obige Beispiel nutzt das geöffnete Verzeichnis, um mit Hilfe der Funktion readdir den Verzeichnisinhalt in eine Liste @Eintraege einzulesen. Anschließend wird das Verzeichnis durch Aufruf der Funktion closedir geschlossen. Das Beispiel sendet dann HTML-Code an einen aufrufenden Browser. Dabei wird die Liste der Verzeichniseinträge ausgegeben.

fork
01-04-2003, 17:06
Das mit WinXP sollte kein Problem sein da gibt's ja ActivePerl (http://www.activestate.com/Solutions/Programmer/Perl.plex) dafür, ist auch gute Doku dabei
Als erstes wirst Du wahrscheinlich File::Find zum rekursiven durchkämmen von Verzeichnisbäumen gebrauchen können
Dann würde ich mir irgendwie so ein paar Sachen zu jeder Datei einlesen und in einem Hash abspeichern(Kompletter Pfad,Dateiname,MD5-Prüfsumme)
Dann würde ich die MD5-Prüfsumme(ist die MD5-Prüfsumme von 2 Dateien gleich handelt es sich mit 99,9%-iger Wahrscheinlichkeit um die gleiche Datei)in einem weiteren Hash als Hash-Schlüssel verwenden und den Hash-Wert bei jeder Datei hochzählen. Ist dieser Wert grösser als 1, ist die Datei mehrfach vorhanden.

benito
01-04-2003, 17:35
Hi (geiles Wetter oder?)
erstmal danke für´s tippen!
Die Sache mit der MD5-Prüfsumme hab ich schon versucht, hier der Code:
#!perl

use strict;
use Digest::MD5;
use File::Find;

my $digest = new Digest::MD5;

my @doppelte = ();
my %checksummen = ();


find( \&compare, 'D:/directory' );

foreach my $file ( @doppelte ){
print "lösche doppelte Datei '$file'... ";
# Kommentarzeichen wegnehmen, falls löschen (erst testen!)
# print unlink($file) ? "OK\n" : "Fehler: $!\n";
}

sub compare {
-f || return;

open( my $file, $_ ) || die "Can't open $File::Find::name: $!\n";

$digest -> addfile( $file );
my $chksum = $digest -> hexdigest;

close $file;

unless( exists $checksummen{$chksum} ){
$checksummen{$chksum} = $File::Find::name;
}
else {
push @doppelte, $File::Find::name;
}
}


Aber das Prob: das Script gibt mir (ohen Witz, hab´s ungefähr 20 * versucht) ca. 80 % der Dateien in den Unterverzeichnissen
zurück, die definitiv (ganz sicher) NICHT die "gleichen" Dateine mit "unterschiedlichen" Namen sind, bin zwar kein Mädchen,
aber langsam fang ich an zu weinen.... war bei spotllight.de, hab da auch diesen Code her, aber der Typ meldete sich nicht mehr,
is auch nur gerecht, hat wahrscheinlich schon genug Nerven mit mir verloren.
Leider funkt dat nicht so.... schade, find den Code wirklich genial! Danke @ joeyfle!
Kann mir jemand bitte bitte das Script so umbauen, das wirklich nur <gleiche> Dateien, für gleiche <Einträge> gefunden werden?
Wär auch bereit eine kleine Überweisung dafür springen zu lassen (30 Euro??) Ohne Witz, weil jetzt will ich es wirklich wissen, häng
über den Prob schon mehr als 1 1/1 Wochen!
Haut rein! Kein Scherzangebot, bin bereit Lehrgeld zu zahlen, Pech für mich!
Cu
B.

fork
01-04-2003, 20:32
Da hat übrigens schon mal einer nach gefragt...

http://www.mrunix.de/forums/showthread.php?s=&threadid=30977

benito
02-04-2003, 18:21
Danke erstmal!
Hab den Link gelesen, die Jungs haben es ja über die Shell gelöst, würd ich ja auch
gern, aber das Ganze muß halt auf einer Winkiste laufen.
Das Script weiter ober is glaub ich schon der richtige Ansatz! Nur gibt es halt alle Dateien zurück
statt doppelte, verdammt!
Keine Ahnung was ich daran ändern sollte um es meinen Bedürfnissen nach zu korrigieren?
Bin euch für jede Hilfe dankbar, aber langsam hab ich keine Energie mehr die Nuß zu k(n)acken!
CU
B.

fork
02-04-2003, 22:54
ich schau' mir das mal an. Habe aber ATM schwer zu tun.

Fir3fly
03-04-2003, 06:55
http://whatpix.sourceforge.net/

Gruss

Fir3fly