Hello, Can you please help me with the following scenario in Perl scripting? I want to compare two text files and save output of this comparision in third file with flag PP. So basically, the word common in both the text files should be printed with a flag |PP on the second text file.

File1.txt -
abc
efg
xyz

File2.txt
abc
efh
pqr

Expected output is - File2.txt
abc |PP
efg
xyz
efh
pqr

I have tried using the following code and end up getting bunch of errors , please advise

use strict;
use warnings;
use autodie;

my $f1 = shift || "File 1.txt";
my $f2 = shift || "File 2.txt";
my %results;
open my $file1, '<', $f1;
while (my $line = <$file1>) { $results{$line} = 1 }
open my $file2, '<', $f2;
while (my $line = <$file2>) { $results{$line}++ }
foreach my $line (sort { $results{$b} <=> $results{$a} } keys %results) {
    print "$results{$line}: \t Match", $line if $results{$line} > 1;
}

Hi debayanenator,

One would have love to see the bunch of errors that you are having.
However, the routes you took in solving the problem will only give you hash entry that has only one as the value.

What you could do is use an hash to get the data in file 1, then open and read through file 2, and while you are reading, check if the hash that contain data from file1, has a corresponding value in file2. If yes, update the key of the hash, if not, make a new entry in the hash.

lastly, sort your hash and print out your keys. You should have your solution.

Below is an example using the values the OP gave. Please note that I use a module called Inline::Files, instead of opening files. This code works perfectly, but OP will have to use open function and print the output as so desire.

use warnings;
use strict;
use Inline::Files;
use Data::Dumper;

my $result = {};

# read from a first file
while(<FILE1>) {
    chomp;
    next if /^$/; # get the next line if empty line
    $result->{$_}++;    
}

# read the second file
while(<FILE2>) {
    chomp;
    next if /^$/;

    # if line is same with that 
    # an hash key in file 1
    if ($result->{$_}) {

    # delete the entry
        delete $result->{$_};

    # then join line with the 
    # word PP and create a new entry
    $result->{join " |"=> $_,"PP"}++;
    }
    else {
        $result->{$_}++;
    }
}

# sort the hash keys from the two files
# and out put your result.
{
    $Data::Dumper::Sortkeys = 1;
    print Dumper $result;
}


__FILE1__
abc
efg
xyz

__FILE2__
abc
efh
pqr

**Output: **

$VAR1 = {
          'abc |PP' => 1,
          'efg' => 1,
          'efh' => 1,
          'pqr' => 1,
          'xyz' => 1
        };

Hi 2teez ,

Thanyou for you prompt reply. Really appreciate it.
I am getting an error while executing the code and it says

"Can't locate Inline/Files.pm in @INC (@INC contains : C:/Perl/site/Lib)
compilation aborted".

Please advise
Do i need to install the module separately ?

Edited 6 Months Ago by debayanenator

Hi,
To use the script like you have it, you have to install the module from CPAN. But really you don't have to.
Just use open function, and read your files using a while loop, instead of using Inline::FIles

That worked !!! Thanks a lot , just that I made few modifications to get the desired output and using open function instead of Inline :: Files.
However , I have one question. I really dont want my output to show the number of occurences of the same word , is there a way to get rid of it ?
The output that the program gives .

$VAR1 = {
          'abc |PP' => 1,
          'efg' => 1,
          'efh' => 1,
          'pqr' => 1,
          'xyz' => 1
        };

Desired Output :

$VAR1 = {
          'abc |PP'
          'efg' 
          'efh' 
          'pqr' 
          'xyz'
        };

Just dont need this ' => Number of occurences '. Any ideas ?

Hi debayanenator,

Sorry, this is coming a bit late.

You can use a for loop with the keys of the hash, which contain the data you wanted. Like so:

print $_, $/ for (sort{$a cmp $b} keys %{$result});

It should give you the result you wanted.

Edited 5 Months Ago by 2teez