---- A program to identify possible duplicates in the filesystem. For now the only criterias are (of course) the filename, the modification time and the size. Later on I will add a crc-check. Example: dupfind d:/pgm/tcl/usr/tst > report.txt A report (output) example: Startverzeichnis : D:/PGM/tcl/usr/Tst Suchmaske : * Pruefungsdatum : 19.07.2006-14:17:50 Dateien gefunden : 5935 Datei: .htaccess - Anzahl: 2 - Groesse: 171 - Zeit: 13.03.2001-07:57:20 - Ordner: D:/PGM/tcl/usr/Tst/httpd351pack/tclhttpd.vfs/htdocs/access/bydir D:/PGM/tcl/usr/Tst/WebSrv1/lib/tclhttpd3.4.3/htdocs/access/bydir Datei: .htaccess - Anzahl: 2 - Groesse: 223 - Zeit: 13.03.2001-07:17:52 - Ordner: D:/PGM/tcl/usr/Tst/httpd351pack/tclhttpd.vfs/htdocs/access/multiple D:/PGM/tcl/usr/Tst/WebSrv1/lib/tclhttpd3.4.3/htdocs/access/multiple Datei: .index - Anzahl: 2 - Groesse: 39 - Zeit: 05.05.2006-12:27:55 - Ordner: D:/PGM/tcl/usr/Tst/httpd342pack/daksite/wwwroot/wikihist/ccpm D:/PGM/tcl/usr/Tst/httpd351pack/daksite/wwwroot/wikihist/ccpm : : : Anzahl mehrfache : 933 Bytes redundant : 37423637 ---- '''Script:''' ################################################################################ # # Skript : dupfind.tcl # Stand : 19.07.2006 # Status : Entwurf, lauffähig # Autor : M.Hoffmann # Sprache : Tcl # Zweck : Erkennen mehrfach vorhandener Dateien anhand Name, Grösse, Zeit # Aufruf : dupfind (startdir) [(suchmaske)|*] # Notizen : - CRC-Bildung sollte nach Eingrenzung durchgeführt werden # - Dateigrössen sauber formatiert ausgeben (b,k,m,g) - der Code ist # irgendwo schon vorhanden) # - Optional verschiedene Ausgabeformate (Sort, Spalten etc.) # ################################################################################ #******************************************************************************* # Direkt aus Modul eingefügt (und abgestrippt), damit sdx qwrap möglich # schlecht: MITTLERER Parameter ist wahlfrei... #******************************************************************************* #****h* Library/globx.tcl # # NAME # # globx.tcl - Erweiterter Globbefehl (bearbeitet Verzeichnisbäume) # v0.03, 09.12.2004 # # AUTHOR # # M.Hoffmann, © 2004 # # PORTABILITY # # Siehe TCL; getestet nur Win2000/XP # # USAGE # # -- package require globx # ALLE ORDNER INKL. ALLEN SUBORDNERN UND DATEIEN, DIE SUCHMASKE ENTSPRECHEN: # -- set files [globx startDir pattern] # oder # proc callback fileName {...} # -- set numFiles [globx startDir pattern callback] # ALLE ORDNER INKL. SUBORDNERN: # -- set dirs [globx2 startDir] # oder # proc callback dirName {...} # -- set numDirs [globx2 startDir callback] # # NOTES # # -- Nicht-rekursive Variante # -- Bei Benutzung eines Callbacks kommen die Namen unsortiert herein # -- Verzeichnisse werden immer ALLE durchsucht (*), Dateien JE NACH SUCHMASKE # -- HIDDEN Entries müssen im Quelltext leider gesondert behandelt werden # -- Tests mit globx_test.tcl, globx2_test.tcl # -- ACHTUNG: Um die selben Ergebnisse wie unter DOS zu erreichen, muss * # anstelle von *.* als Suchmaske angegeben werden! # # TODO # # -- Namespace # # HISTORY # # v0.01 06.02.2004 - Erste dokumentierte, einsatzfähige Version # v0.02 21.10.2004 - Überarbeitung gemäss Wiki-Änderung-Empfehlung # v0.03 09.12.2004 - Nur Ordnerbäume verarbeiten mit globx2 # # SOURCE proc globx {startDir {search *} {cb ""}} { set dirStack [list [file normalize $startDir]] set files {} set fc 0 while {[llength $dirStack]} { set newStack {} foreach dir $dirStack { # temporary var's only because eventually using CallBack set fn [glob -noc -typ f -dir $dir -- $search] set fh [glob -noc -typ {f hidden} -dir $dir -- $search] if {[string equal $cb ""]} { eval lappend files $fn $fh } else { foreach f [concat $fn $fh] { incr fc uplevel [list $cb $f] } } set dn [glob -noc -typ d -dir $dir *] set dh [glob -noc -typ {d hidden} -dir $dir *] # eval lappend newStack $dn $dh; # v0.01 # Wikipatch Start v0.02 --- foreach newDir [concat $dn $dh] { set theDir [file tail $newDir] if {[string equal $theDir "." ] || \ [string equal $theDir ".."]} { # Don't push this, otherwise entering an endless # loop (on UNIX, at least) } else { lappend newStack $newDir } } # Wikipatch Ende --- } set dirStack $newStack update; # keep Background alive } if {[string equal $cb ""]} { return [lsort $files] } else { return $fc } } #******************************************************************************* proc callBack {ff} { global f global infos global v set fn [string tolower [string trim [file tail $ff]]] set fd [file dirname $ff] catch { # catch shouldn't be required here in theorie, but in practise it is... set size [file size $ff] set info [list $fn $size [file mtime $ff]] lappend f($info,dirs) $fd set dl [llength $f($info,dirs)] if {$dl == 2} { # merken, welche später auszugeben sind, aber nur 1x lappend infos $info puts -nonewline stderr . flush stderr } if {$dl > 1} { # verschwendete GesamtBytes hier mitzählen, spart Mult später... incr v $size } }; # show no erros from catch so far } #******************************************************************************* #******************************************************************************* # # MAIN # #******************************************************************************* #******************************************************************************* if {[llength $argv] < 1} { puts { dupfind 0.1 MHo Auffinden von mehrfach gespeicherten Dateien anhand Name, Datum, Modifikationszeit (Erweiterung durch CRC-Check und weitere Optionen sind geplant). Gebrauch: dupfind (startverzeichnis) [(suchmaske)|*] > ausgabe.datei ACHTUNG: *.* findet nur Dateien mit einer .Nameserweiterung! } exit 255; } elseif {[llength $argv] == 1} { lappend argv * } #******************************************************************************* # Globale Variablen #******************************************************************************* set infos {} array set f {} set v 0 #******************************************************************************* puts "Startverzeichnis : [file normalize [lindex $argv 0]]" puts "Suchmaske : [lindex $argv 1]" puts "Pruefungsdatum : [clock format [clock seconds] -format %d.%m.%Y-%T]" puts {} set numFiles [globx [lindex $argv 0] [lindex $argv 1] callBack] puts stderr \n\n; puts "Dateien gefunden : $numFiles" puts {} if {$numFiles == 0} { exit 1; } #******************************************************************************* foreach info [lsort $infos] { puts "Datei: [lindex $info 0] - Anzahl: [llength $f($info,dirs)] -\ Groesse: [lindex $info 1] -\ Zeit: [clock format [lindex $info 2] -format %d.%m.%Y-%T] - Ordner:\n" foreach dir $f($info,dirs) { puts " $dir" } puts {}; } puts "\nAnzahl mehrfache : [llength $infos]" puts "\nBytes redundant : $v\n" exit 0; ---- To compile, use sdx qwrap -runtime tclkitsh.exe ---- More infos follow later ;-)