Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re^2: Simple comparison of 2 files

by Q.and (Novice)
on Jul 27, 2016 at 19:12 UTC ( [id://1168671] : note . print w/replies, xml ) Need Help??


in reply to Re: Simple comparison of 2 files
in thread Simple comparison of 2 files

Of course. The real input files have many more variables, but I've tried to simplify both the code and input files without losing the main point of the script. By match, I just mean does $FILE1letter equal $FILE2letter, as in A==A. By no match, I mean $FILE1letter = A and $FILE2letter=B, so A!=B. The goal of the real script is really not to just print matches and mismatches, but to do many things within each conditional, but I realized that my if statement was not working correctly, as it was printing even when there was no match and I think the larger problem is the looping structure of the entire code. Thanks for the help.

Replies are listed 'Best First'.
Re^3: Simple comparison of 2 files
by Paladin (Vicar) on Jul 27, 2016 at 19:24 UTC
    Ok, that makes it clear. Your issue is with the line:
    if ($FILE1letter == $FILE2letter) {
    Use the eq operator to compare strings. == compares numerically.

      and the next issue is that you're only looping thru the second file once; to be able to compare every line of file1 against every line of file2, you're going to need to parse the second file multiple times (ie, nested loop); alternatively, grab all of file2 into an appropriate data structure, and compare each line of file1 to each entry in the file2 data structure (or vice versa, or both into data structures, then just compare the data)

      update1

      #!perl open (FILE1, $ARGV[0]); while ($_ = <FILE1>) { chomp; @FILE1 = split; ($FILE1letter, $FILE1number) = @FILE1; open (FILE2, $ARGV[1]); while( $two = <FILE2> ) { @FILE2 = split(' ',$two); ($FILE2letter, $FILE2number) = @FILE2; # print "$FILE1letter from FILE1 with number $FILE1numbe +r and $FILE2letter from FILE2 with $FILE2number match\n"; # prints the same as below if ($FILE1letter eq $FILE2letter) { print "$FILE1letter from FILE1 with number $FILE1number an +d $FILE2letter from FILE2 with number $FILE2number match\n"; } else { print "$FILE1letter from FILE1 with number $FILE1number an +d $FILE2letter from FILE2 with number $FILE2number DO NOT match\n"; } } close (FILE2); } __END__ C:\Temp>perl ab.pl a b A from FILE1 with number 1_1 and A from FILE2 with number 2_1 match A from FILE1 with number 1_1 and B from FILE2 with number 2_2 DO NOT m +atch A from FILE1 with number 1_2 and A from FILE2 with number 2_1 match A from FILE1 with number 1_2 and B from FILE2 with number 2_2 DO NOT m +atch B from FILE1 with number 1_3 and A from FILE2 with number 2_1 DO NOT m +atch B from FILE1 with number 1_3 and B from FILE2 with number 2_2 match C from FILE1 with number 1_4 and A from FILE2 with number 2_1 DO NOT m +atch C from FILE1 with number 1_4 and B from FILE2 with number 2_2 DO NOT m +atch
        Excellent, this is exactly the issue I was dealing with- thank you!

      Oh man, super rookie mistake there- thanks for catching that. However, even when corrected, it prints:
      A from FILE1 with number 1_1 and A from FILE2 with number 2_1 match
      A from FILE1 with number 1_2 and B from FILE2 with number 2_2 DO NOT match
      B from FILE1 with number 1_3 and from FILE2 with number DO NOT match
      C from FILE1 with number 1_4 and from FILE2 with number DO NOT match

      and is still is missing two of the matches and two of the mismatches, so that's in the looping.

Re^3: Simple comparison of 2 files
by Marshall (Canon) on Jul 27, 2016 at 19:47 UTC
    Ok, try this below. You need an array to describe file2 so that you can loop over it for each entry in file1. use strict; and use warnings; as a huge help. I would only use all CAPS for bareword file handles. I changed the names accordingly.
    #!usr/bin/perl use warnings; use strict; use Data::Dumper; my $file1 = 'A 1_1 A 1_2 B 1_3 C 1_4 '; my $file2 = 'A 2_1 B 2_2 '; open FILE1, "<" , \$file1 or die "unable file1 $!"; open FILE2, "<", \$file2 or die "unable file2 $!"; my @file2; #need to compare each line in file1 against all while (<FILE2>) #lines in file2, so create an array of file 2 { chomp; push @file2, $_; } while (<FILE1>) { chomp; my ($file1letter, $file1number) = split (' ', $_); foreach my $line2 (@file2) { my ($file2letter, $file2number) = split (' ', $line2); if ($file1letter eq $file2letter) { print "$file1letter from FILE1 with number $file1number and +$file2letter from FILE2 with number $file2number match\n"; } else { print "$file1letter from FILE1 with number $file1number and +$file2letter from FILE2 with number $file2number DO NOT match\n"; } } } __END__ A from FILE1 with number 1_1 and A from FILE2 with number 2_1 match A from FILE1 with number 1_1 and B from FILE2 with number 2_2 DO NOT m +atch A from FILE1 with number 1_2 and A from FILE2 with number 2_1 match A from FILE1 with number 1_2 and B from FILE2 with number 2_2 DO NOT m +atch B from FILE1 with number 1_3 and A from FILE2 with number 2_1 DO NOT m +atch B from FILE1 with number 1_3 and B from FILE2 with number 2_2 match C from FILE1 with number 1_4 and A from FILE2 with number 2_1 DO NOT m +atch C from FILE1 with number 1_4 and B from FILE2 with number 2_2 DO NOT m +atch
    update: I didn't see the code from pryrt before I hit the send button. The code above reads FILE2 into a memory array. Opening and reading a file is an "expensive" operation both CPU and time wise. Unless FILE2 is humongous, reading it once from the disk is the best approach.