Compare common fields from two text files

terrylau's Avatar, Join Date: Jul 2009
Go4Expert Member
Hi guys, Perl newbie here. Need help here. I've got two text file - File1.txt and File2.txt. The files consist of :

File1.txt
Field1 Field2 Field3 Field4 Field5
A 1 1 1 A1
B 2 2 2 B2
C 3 3 3 C3
D 4 4 4 D4
E 5 5 5 E5
F 6 6 6 F6

File2.txt
Field2 Field3 Field4
1 1 1
2 2 2
3 3 3

I want to check both files, and if both have the same values for Field2,Field3,Field4 - in this example, the output should be the lines from File1.txt
A 1 1 1 A1
B 2 2 2 B2
C 3 3 3 C3

It should do checking by line to whole file rather than line1 compare line1, line2 compare line2, etc.
Meaning it should be something like this :

Line1(File1.txt) compare all contents of File2.txt, print line from File1.txt with common values
Line2(File1.txt) compare all contents of File2.txt, print line from File1.txt with common values
Line3(File1.txt) compare all contents of File2.txt, print line from File1.txt with common values

and not :

Line1(File1.txt) compare Line1(File2.txt), print line from File1.txt if have common values
Line2(File1.txt) compare Line2(File2.txt), print line from File1.txt if have common values
Line3(File1.txt) compare Line3(File2.txt), print line from File1.txt if have common values


Here's my code but I"m not too sure what's wrong as I'm seem to have the wrong output.
Code:
 
  my %seen;
  my $line;
  my @data;
   
  open(A, "File1.txt") or die "...";
  while ($line = <A>)
              {
                          @data = split(" ",$line);
                          ($Field2, $Field3, $Field4) = ($data[1], $data[2], $data[3]);
                          $seen{$Field2, $Field3, $Field4}= 1;
              }
  close(A);
   
  open(B, "File2.txt") or die "...";
  while ($line = <B>)
              {
                          @data = split(" ",$line);
                          ($Field2, $Field3, $Field4) = ($data[0], $data[1], $data[2]);
                          $seen{$Field2, $Field3, $Field4} +=2;
              }
  close(B);
   
  while (my ($key, $val) = each %seen) {
    if ($val == 1) {
      # $key is in first file but not second
  print " File 1 - $Field2, $Field3, $Field4\n"
    } elsif ($val == 2) {
      # $key is in second file but not first
  print " File 2 - $Field2, $Field3, $Field4\n"
    } else {
      # key is in both files
  print " Both file - $Field2, $Field3, $Field4\n"
  }
  }
Appreciate the help or suggestion for other ways to do this. Thanks.
pradeep's Avatar, Join Date: Apr 2005
Team Leader
Here's it

Code: Perl
#!/usr/bin/perl

my %seen;
my $line;
my @data;

open( A, "File1.txt" ) or die $!;
my $line = <A>;    # first line
while ( $line = <A> )
{
    chomp($line);
    @data = split( " ", $line );
    next unless(@data);
    ( $Field2, $Field3, $Field4 ) = ( $data[1], $data[2], $data[3] );
    $seen{"$Field2,$Field3,$Field4"} = 1;
}
close(A);

open( B, "File2.txt" ) or die $!;
my $line = <B>;    # first line
while ( $line = <B> )
{
    chomp($line);
    @data = split( " ", $line );
    next unless(@data);
    ( $Field2, $Field3, $Field4 ) = ( $data[0], $data[1], $data[2] );
    $seen{"$Field2,$Field3,$Field4"} += 2;
}
close(B);

while ( my ( $key, $val ) = each %seen )
{
    if ( $val == 1 )
    {
        # $key is in first file but not second
        print " File 1 - $key\n";
    }
    elsif ( $val == 2 )
    {
        # $key is in second file but not first
        print " File 2 - $key\n";
    }
    else
    {
        # key is in both files
        print " Both file - $key\n";
    }
}