http://www.perlmonks.org?node_id=1208783

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

Given below is a perl script which compares one column from one file and checks with a key if it exists in another file and exists in file2.
use strict; use warnings; use Data::Dumper; my ($file1 ,$file2,$file3)= @ARGV; open(my $fh, '>', $file3) or die $!; #reading file1 into a hash my %hash; my @fields; open( my $fh1, '<', $file1 ) or die $!; while ( my $line = <$fh1> ) { chomp $line; next if $line =~ /^\s*$/; $line =~ s/^\s+|\s+$//g; $hash{$line} = 1; } #print Dumper(\%hash); close $fh1; open( my ($fh2), $file2 ) or die $!; while ( my $row = <$fh2> ) { chomp $row; #print "$row\n"; next if $row =~ /^\s*$/; $row =~ s/^\s+|\s+$//g; my (@fields) = split( /\|/, $row ); # print "$fields[0]\n "; if ( exists $hash{ $fields[0] } ) { print $fh "$row\n"; } } close $fh; close $fh2;
Now i want it to be able to compare with N number of columns like file 1 having more than 1 columns. What modifications are to be done in this ? The need is to generalize the script and make it a compare utility. Kindly guide
SO basically These are the files
File1
L| D
L| C
L| C
File2
AE|A|D||
A|A|P| |
A|A|P| |
A|A|P| |
So if i pass Col2 from file1 as parameter and Col3 from file2 as second the output should be
AE|A|D||
Since this contains the column2 value from file1 in its column3

Replies are listed 'Best First'.
Re: Comparision Utility PERL
by hippo (Bishop) on Feb 09, 2018 at 09:02 UTC
    Kindly guide

    Since it's trivial:

    for my $fieldnum (0 .. $#fields) { if ( exists $hash{ $fields[$fieldnum] } ) { print $fh "$row\n"; next; } }

    Untested, since the original code provided is not an SSCCE.

    Update: Note that vighneshmufc has altered the parent post to change the spec. This and the rest of the subthread may make less sense than originally.

      UPDATE
      i didnt understand this what did you do ?
      i need to run this file as perl filename.pl file1 file2 file3 Col2 col3
      i am very new to this . Also i reduced the sample.

        I have added a loop so that your comparison of one field against the row becomes a comparison of all fields against the row. That is what you wanted, no?

        Have a look at each statement in that block one by one. If you don't understand anything there, try to find it in the documentation with perldoc. If you still don't understanding it you can say so here, specifying where you looked and how the documentation you read did not make it clear. You may also peruse the Tutorials here for further guidance.

        Happy learning!

Re: Comparision Utility PERL
by Marshall (Canon) on Feb 09, 2018 at 10:32 UTC
    I and others have tried before to help you.
    #!/usr/bin/perl use strict; use warnings; use Inline::Files; my %col2file1; #use better name! while (<FILE1>) { next if /^\s*$/; #skip blank lines my $col2 = (split /\|/, $_)[1]; $col2 =~ s/^\s*//; #delete leading spaces $col2 =~ s/\s*$//; #delete trailing spaces $col2file1{$col2} = 1; } while (<FILE2>) { next if /^\s*$/; #skip blank lines my $col3 = (split /\|/,$_)[2]; $col3 =~ s/^\s*//; #delete leading spaces $col3 =~ s/\s*$//; #delete trailing spaces print if $col2file1{$col3}; } #prints: "AE|A|D|| " __FILE1__ L| D L| C L| C __FILE2__ AE|A|D|| A|A|P| | A|A|P| | A|A|P| |
      yes i understood it but right now i have to split from input given from the command line. How do i modify this code with respect to that ? i am sorry for such nuisance but i am trying to learn :)
        and it is not column2 and column3 it is just for an example. The user should input any column from each file he wishes for like it has to be dynamic perl filename.pl file1 file2 col1fromfile1 col2fromfile2
Re: Comparision Utility PERL
by tybalt89 (Monsignor) on Feb 09, 2018 at 23:00 UTC
    #!/usr/bin/perl # http://perlmonks.org/?node_id=1208783 use strict; use warnings; my ($match, $input, $output, $colmatch, $colinput) = @ARGV == 5 ? @AR +GV : qw( d.file1 d.file2 d.output 2 3 ); # for testing, replace with usag +e my %matchs = map { s/^\s+|\s+$//gr, 1 } grep defined, map +(split /\|/)[$colmatch - 1], do { local @ARGV = $match; <> }; open my $fh, '>', $output or die "$! opening $output"; print $fh grep $matchs{ ((split /\|/)[$colinput - 1] // '') =~ s/^\s+|\s+$//gr + }, do { local @ARGV = $input; <> }; close $fh;