Perl CookbookPerl CookbookSearch this book

8.22. Comparing the Contents of Two Files

8.22.1. Problem

You have two files and want to see whether they're the same or different.

8.22.2. Solution

Use the standard File::Compare module with filenames, typeglobs, or any indirect filehandles:

use File::Compare;

if (compare($FILENAME_1, $FILENAME_2) =  = 0) {
  # they're equal
}

if (compare(*FH1, *FH2) =  = 0) {
  # they're equal
}

if (compare($fh1, $fh2) =  = 0) {
  # they're equal
}

8.22.3. Discussion

The File::Compare module (standard as of v5.8 and available on CPAN if you have an earlier version of Perl) compares two files for equality. The compare function, exported by default, returns 0 when the files are equal, 1 when they differ, and -1 when any error occurs during reading.

To compare more than two filehandles, simply loop, comparing two at a time:

# ensure all filehandles in @fh hold the same data
foreach $fh (@fh[1..$#fh]) {
  if (compare($fh[0], $fh)) {
    # $fh differs
  }
}

If you want details of exactly how two files differ, use the Text::Diff module from CPAN:

use Text::Diff;

$diff = diff(*FH1, *FH2);
$diff = diff($FILENAME_1, $FILENAME_2, { STYLE => "Context" });

In addition to filehandles, diff can also take filenames, strings, and even arrays of records. Pass a hash of options as the third argument. The STYLE option controls the type of output returned; it can be "Unified" (the default), "Context", or "OldStyle". You can even write your own class for custom diff formats.

The value returned by diff is a string similar to the output of the diff(1) program. This string is in valid diff format, suitable for feeding into patch(1). Although Text::Diff will not always produce the same output as GNU diff, byte for byte, its diffs are nevertheless correct.

8.22.4. See Also

The documentation for the standard File::Compare module; the documentation for the CPAN module Text::Diff; the diff(1) and patch(1) manpages.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.