dilip_val has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I am trying to compare two files which have content like
/dir1/file1
/dir1/file2
/dir1/file3

with another file which has content like
/dir2/file1
/dir2/file2
/dir2/file3

I need to compare each line in file tst1 with corresponding line in file tst2 and determine if they are same , that is find out if there is any difference in thier content , but i am ending up with errors ,compare file in tst1 and file 1 in tst2 , compare file2 in tst1 and file2 in tst2 and so on. could anyone pls help me as i am a very intermittent user of scripting
#! /usr/bin/perl open (IF,"<tst1"); open (IF2,"<tst2"); my(@tst1) = <IF>; my(@tst2) = <IF2>; my ($i); my ($j); foreach $i (@tst1) { chomp($i); print "$i\n"; foreach $j (@tst2) { chomp($j); print "$j\n"; `diff $i $j > /dev/null`; `echo $?`; } } close(IF); close(IF2);
  • Comment on compare two files line by line and perform a diff on each coressponding line
  • Download Code

Replies are listed 'Best First'.
Re: compare two files line by line and perform a diff on each coressponding line
by moritz (Cardinal) on Jun 01, 2010 at 14:56 UTC
    This looks hairy for several reasons.
    • diff $i $j doesn't compare the strings $i and $j, but interprets them as file names. I see no indication in your textual description that that's the goal. If you just want to compare strings for equality, use $i eq $j in Perl.
    • `program > /dev/null` doesn't make any sense to me. First throw away the output, then capture it, then discard it again by putting it in void context...
    • Since each `...` line starts its own shell, the exit status from diff command won't be available in `$?`.
    Perl 6 - links to (nearly) everything that is Perl 6.
Re: compare two files line by line and perform a diff on each coressponding line
by jethro (Monsignor) on Jun 01, 2010 at 14:40 UTC

    If you only want to compare each line of tst1 to the corresponding line in tst2 you don't need two loops. Use something like this:

    while (@tst1) { $i= shift @tst1; $j= shift @tst2; chomp($i); chomp($j); `diff $i $j > /dev/null`; `echo $?`; }

    You thought you needed two loops because you wanted to step through two arrays, but you need only one loop that makes a simultaneous step through both arrays.

      Thanks jethro and all , this seemed to work
      #! /usr/bin/perl use File::Compare; open (IF,"<tst1"); open (IF2,"<tst2"); my(@tst1) = <IF>; my(@tst2) = <IF2>; my ($i); my ($j); while (@tst1) { $i=shift @tst1; $j= shift @tst2; chomp($i); chomp($j); #print "$i\n"; #print "$j\n"; if (compare("$i","$j") == 0) { print "$i $j are equal\n"; } else { print "$i $j are not equal\n"; } } close(IF); close(IF2);
Re: compare two files line by line and perform a diff on each coressponding line
by toolic (Bishop) on Jun 01, 2010 at 14:46 UTC
    You are diffing all files from dir1 with all files from dir2. If you only want to diff file1 vs. file1, etc. (UNTESTED):
    use strict; use warnings; use File::Basename; my @tst1 = qw( /dir1/file1 /dir1/file2 /dir1/file3 ); my @tst2 = qw( /dir2/file1 /dir2/file2 /dir2/file3 ); chomp @tst1; chomp @tst2; for my $t1 (@tst1) { for my $t2 (@tst2) { next unless basename($t1) eq basename($t2); my $status = system "diff $t1 $t2 > /dev/null"; print "$status\n"; } }
Re: compare two files line by line and perform a diff on each coressponding line
by Khen1950fx (Canon) on Jun 02, 2010 at 07:35 UTC
    In this script, I compared two directories, compared two files from those directories, and did a diff on the two files.
    #!/usr/bin/perl use strict; use warnings; use File::Compare; use File::DirCompare; use Text::Diff; use Text::Diff::Table; use YAML; use YAML::Dumper; my $dir1 = '/usr/lib/perl5/5.8.8/CGI'; my $dir2 = '/usr/lib/perl5/5.8.8/Shell'; File::DirCompare->compare($dir1, $dir2, sub { my ($a, $b) = @_; if (! $b) { printf "Only in %s: %s\n", dirname($a), basename($a); } elsif (! $a) { printf "Only in %s: %s\n", dirname($b), basename($b); } else { print "Files $a and $b differ\n"; } }); if ($dir1 eq $dir2) { print "They're equal\n"; } else { print "They're not equal\n"; } my $tst1 = '/usr/lib/perl5/5.8.8/CGI.pm'; my $tst2 = '/usr/lib/perl5/5.8.8/Shell.pm'; my $diff = Text::Diff::Table->new; $diff = diff $tst1, $tst2, { STYLE => "Table" }; my $dumper = YAML::Dumper->new; $dumper->indent_width(4); print $dumper->dump($diff); if (compare($tst1, $tst2) == 0) { print "They're equal\n"; } else { print "They're not equal\n"; }
Re: compare two files line by line and perform a diff on each coressponding line
by JavaFan (Canon) on Jun 01, 2010 at 14:35 UTC
    Why not just use the diff utility? Or perhaps comm? No need to reinvent the wheel - code reuse doesn't stop at CPAN.
      Why not just use the diff utility?
      That is confusing advice, given the fact that the OP is already using diff. I believe the question is how to use it to avoid unexpected behavior (which the OP did not clearly specify).