#!/usr/bin/perl # # NAME # FindDiffFiles - Find files with same name but different contents. # # SYNOPSIS # FindDiffFiles [pattern] [dir] > DiffFiles # # DESCRIPTION # This script looks thru all the listed directories and their # subdirectories ('.' by default), and makes a table of all the # files whose name matches the pattern (all files by default). It # then runs thru the list in alphabetical order, comparing files # that have the same name, and outputs a list of the pairs with # different contents. This can be useful in finding files that are # supposed to be the same but aren't. # # CAVEATS # There's generally nothing wrong with two files having the same # name but different contents. Consider 'Makefile', for example. # But in some situations, it can be a problem if there are, say, # different foo.c files in different directories. So this program # doesn't do anything about such files; it just finds them for you. # Examining the output list is your problem. # # AUTHOR # John Chambers $| = 1; ($me = $0) =~ s'.*/''; $V = $ENV{"V_$me"} || $ENV{"T_$me"} || $ENV{"D_$me"} || 1; $exitstat = 0; for $a (@ARGV) { if (-d $a) { push(@dir,$a); } elsif (!$pat) { $pat = $a; } else { print STDERR "$me: Extra arg \"$a\" ignored.\n" if $V>0; } } $pat = '.+' if !$pat; @dir = ('.') if !@dir; for $d (@dir) { &loaddir($d); } # Suppress some common file names: undef $files{Makefile}; undef $files{Manifest}; undef $files{HEADER.html}; for $f (sort keys %files) { print "File $f ...\n" if $V>2; next if $f =~ /^\./i; next if $f =~ /readme/i; $l = $files{$f}; @path = split(' ',$l); F1: while ($p1 = shift(@path)) { next F1 if !$p1; ($d1,$i1,$m1,$n1,$u1,$g1,$r1,$s1) = lstat($p1); F2: for $p2 (@path) { next F2 if !$p2; ($d2,$i2,$m2,$n2,$u2,$g2,$r2,$s2) = lstat($p2); next F2 if ($d1 == $d2 && $i1 == $i2); if ($s1 != $s2) { print "Diff $p1\t$p2\n"; } else { if (!open(F1,$p1)) { print STDERR "$me: Can't read $p1 ($!)\n" if $V>0; next F1; } if (!open(F2,$p2)) { print STDERR "$me: Can't read $p2 ($!)\n" if $V>0; $p2 = ''; # Don't look at it again. next F2; } while ($l1 = ) { if (!($l2 = )) { print "Diff $p1\t$p2\n"; next F2; } if ($l1 ne $l2) { print "Diff $p1\t$p2\n"; next F2; } } print "Same $p1\t$p2\n" if $V>2; } } } } exit $exitstat; sub loaddir { local($d) = @_; local(*D,$f,$p); if (opendir(D,$d)) { print "Scan $d ...\n" if $V>1; for $f (readdir(D)) { next if ($f =~ /^\.*$/); $p = ($d eq '.') ? $f : "$d/$f"; if (-d $p) {&loaddir($p); next} next if ($f !~ $pat); $files{$f} .= "$p "; } closedir(D); } else { print STDERR "$me: Can't read dir $d ($!)\n" if $V>0; } }