in reply to iterating through a hash?

Why do you open file2 for every key in %hash1, go through that file from start to end to only look at the key at one line?

It suffices to open file2 once, read in key/value pairs (as you did with file1); whilst doing so you can find out whether the current key exists in file1:

open TWO, '<', $FILE2; # better be explicit ;-) while (<TWO>) { chomp; # correct indent level is here. my ($key,$value) = split /\s+/,$_; print "$key NOT IN FILE 1\n" unless $hash1{$key}; $hash2{$key} = $value; }
Now you have %hash1 and %hash2 populated; you can iterate over the key lists and see if they exist in each other, and if so, whether their values are identical:
foreach my $key (keys %hash1) { if(exists($hash2{$key}) { if($hash1{$key} == $hash2{$key}) # '==' if numeric, 'eq' if + string { ... } else { ... } } else # this is the case you missed - $key not in file2 { ... } }

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Replies are listed 'Best First'.
Re^2: iterating through a hash?
by Cristoforo (Curate) on Sep 17, 2006 at 20:22 UTC
    The solution could even use just 1 hash if the whitespace separating the name and number is the same (same number of tabs or spaces).
    #!/usr/bin/perl use strict; use warnings; open FH2, "o44.txt" or die $!; my %file2 = map{ $_ => 1} <FH2>; close FH2 or die $!; open FH1, "o33.txt" or die $!; while (<FH1>) { s/\s+/$file2{ $_ } ? " OK " : " WRONG "/e; print; } close FH1 or die $!;
Re^2: iterating through a hash?
by graff (Chancellor) on Sep 17, 2006 at 21:28 UTC
    Cristoforo is right about needing only one hash to do this, but it doesn't need to depend on having identical whitespace in the two files:
    use strict; my %hash; open( F, "<", "file1" ) or die "file1: $!"; while (<F>) { my ( $name, $val ) = split; $hash{$name} = $val; } open( F, "<", "file2" ) or die "file2: $!"; while (<F>) { my ( $name, $val ) = split; if ( exists( $hash{$name} ) { my $status = ( $hash{$name} eq $val ) ? 'OK':'WRONG'; print "$name\t$status\t$hash{$name}\n"; delete $hash{$name}; # don't need this anymore } } # any keys left in hash are cases where a file1 name was not found in +file2 # so print those now: if ( keys %hash ) { print "\nNames not found in file2:\n"; print "$_\t$hash{$_}\n" for ( sort keys %hash ); }
    (updated the code so that the names are always printed with the values from file1, as per the OP spec.)

    Nothing happens for names in file2 that don't exist in file1, but the OP didn't say that anything needed to be done for those. There was also nothing said about the same name occurring more than once in either file, but maybe the AM won't need to worry about that...

Re^2: iterating through a hash?
by Anonymous Monk on Sep 17, 2006 at 10:23 UTC
    Thank you very much! You are correct, I should have used 2 hashes instead, it's much easier that way...