# dirty code, nur als demo gedacht $datname="test.txt"; open (in,$datname); while (<in>){$inhalt.=$_;} close in; $datei{$datname}=$inhalt; |
# nur Democode zur Veranschaulichung $datname="test.txt"; open (in,$datname); while (<in>){$inhalt.=$_;} close in; $checksumme=generiere_checksumme($inhalt); $files{$checksumme}.="$datname\n"; |
use Digest::MD5 qw(md5); use strict; my %files=(); my %dateien; my @nulllength=(); my @dateisize=(); my @dateien=get_all_files('c:/htdocs/',1,'.shtml'); print "Es wurden ".@dateien." Dateien gefunden\n"; ## Dateilänge holen und merken foreach (@dateien){ my $size=-s $_; # Dateiname + Größe in Skalar schreiben push (@{$dateien{$size}},"$_\|$size]"); } @dateien=(); foreach (keys %dateien){ my @dats=@{$dateien{$_}}; next if @dats<2; # wenigstens 2 Filename müssen da sein push (@dateien,@dats); } %dateien=(); print "Es wurden ".@dateien." mögliche Dateien gefunden\n Generiere Checksummen\n"; foreach (@dateien){ get_checksum($_); } print qq~Dateien mit Nulllaenge:\n~; print join("\n",@nulllength); print qq~\n\nIdentische Dateien:\n~; foreach (keys %files){ print "$files{$_}\n\n" if (split('\n',$files{$_}) >1); } exit; ################### # Parameter # Startdir ohne abschließendes /, aktuelles Verzeichnis = . # Unterverzeichnisse durchsuchen? 1: ja, 0: nein # Dateitypen in form .txt.htm.html , also direkt hintereinander, aber nur wenn nötig # ansonsten wird alles gezeigt ############################################# sub get_all_files{ my $startdir=shift; my $include_subdirs=shift; my $endings=shift; my %endings=(); $endings=~ s/\s//g; my @endings=split('\.',$endings); shift @endings; my $endings=0; $startdir=~ s/\/$//; if (@endings != 0){ $endings=1; # wenn Endungen angegeben foreach (@endings){ $endings{$_}=1; } } @endings=(); my @dateien=(); push (my @all_directories,$startdir); foreach my $akdir(@all_directories){ local *in; opendir (in,$akdir); my @all=readdir(in); closedir in; foreach my $akdatei (@all){ next if ($akdatei eq '..' || $akdatei eq '.'); if (-d "$akdir/$akdatei") { if ($include_subdirs == 1){ push (@all_directories,"$akdir/$akdatei"); next; } } else { if ($endings==0){ push (@dateien,"$akdir/$akdatei"); } else { my @endung=split('\.',$akdatei); my $endung=$endung[-1]; if ($endings{$endung} == 1){ push (@dateien,"$akdir/$akdatei"); } } } } } return @dateien; } ###################### # generiert Checksumme einer Datei ############################################# sub get_checksum{ my $data=''; (my $dateiname, my $dateilaenge)=split('\|',shift); if ($dateilaenge < 1){ push(@nulllength,$dateiname); } else { return if $dateilaenge > 64000000; # Wenn Datei > als 64 Mio. Byte open (my $IN,'<'.$dateiname); binmode($IN); my $checksum = Digest::MD5->new->addfile(*$IN)->b64digest; close $IN; $files{$checksum}.="$dateiname\n"; } } |
###################### # generiert Checksumme einer Datei ############################################# sub get_checksum{ my $data=''; (my $dateiname, my $dateilaenge)=split('\|',shift); if ($dateilaenge < 1){ push(@nulllength,$dateiname); } else { return if $dateilaenge > 64000000; # Wenn Datei > als 64 Mio. Byte open (my $IN,'<'.$dateiname); binmode($IN); my $checksum = Digest::MD5->new->addfile(*$IN)->b64digest; close $IN; $files{$checksum}.="$dateiname\n"; } } |
foreach (keys %files){ print "$files{$_}\n\n" if (split('\n',$files{$_}) >1); } |