09.01.2012 [HE]: I needed a diff procedure in pure Tcl without holding the contents of the file and the result in the memory. ====== # Syntax: # filediff # Description: # Compare two files line by line directly from the local filesystem and provide the result with the stated procs. # with: # = One of the files to compare. # = The other file to compare. # = Procedure to call if two lines are equal. Default is 'cmdEqual'. # = Procedure to call if an addtional row is found in . Default is 'cmdAdd'. # = Procedure to call if an row is found which not exist in . Default is 'cmdDel'. # # Create your own procedures to output the result if you need anything different than simply write to stdout with puts proc filediff {file1 file2 {cmdEqual {cmdEqual}} {cmdAdd {cmdAdd}} {cmdDel {cmdDel}}} { set sourcefid1 [open $file1 r] set sourcefid2 [open $file2 r] set found 1 while {![eof $sourcefid1] && ![eof $sourcefid2]} { set lastmark [tell $sourcefid2] ;# Position in before reading the next line gets $sourcefid1 line1 gets $sourcefid2 line2 if {$line1 eq $line2} { $cmdEqual $line1 continue } # Lines with only whitespace are also equal if {[regexp -- {^\s*$} $line1] && [regexp -- {^\s*$} $line2]} { $cmdEqual {} continue } # From here both lines are unequal set state 0 while {[regexp -- {^\s*$} $line1]} { # If unequal then directly state empty lines in as deleted. $cmdDel $line1 if {![eof $sourcefid1]} { gets $sourcefid1 line1 if {$line1 eq $line2} { $cmdEqual $line1 set state 1 break } } else { break } } if {$state} { continue } # Remember position in and look forward set mark2 [tell $sourcefid2] set mark2a $lastmark set found 0 while {![eof $sourcefid2]} { gets $sourcefid2 line2 if {$line1 ne $line2} { set mark2a $mark2 set mark2 [tell $sourcefid2] } else { # Found a matching line. Everything up to the line before are new lines seek $sourcefid2 $lastmark while {[tell $sourcefid2] <= $mark2a} { gets $sourcefid2 line2 $cmdAdd $line2 } gets $sourcefid2 line2 $cmdEqual $line2 set found 1 break } } if {!$found} { # No matching line found in . Line must be deleted $cmdDel $line1 seek $sourcefid2 $lastmark } } # Output the rest of as deleted while {![eof $sourcefid1]} { gets $sourcefid1 line1 $cmdDel $line1 } # Output the rest of as added while {![eof $sourcefid2]} { gets $sourcefid2 line2 $cmdAdd $line2 } close $sourcefid2 close $sourcefid1 return } proc cmdEqual {txt} { global n puts "=$txt";update } proc cmdAdd {txt} { global n puts "+$txt";update } proc cmdDel {txt} { global n puts "-$txt";update } ====== <>Category Application | Category Algorithm | Category File