0
votes

I am pretty new to Perl and need to accomplish a task quickly. Any help is appreciated!

I have two hash of arrays as follows:

Hash 1
-------
abc.txt: ['0744','0']
xyz.txt: ['0744','0']

Hash 2
-------
abc.txt: ['0766','0']
x.txt: ['0744','0']

I have to compare these 2 hashes print 3 things:
1. Files Added in Hash2
2. Files Missing in Hash2
3. Files(keys) which are present in both hashes but there attributes(values) are different.

print "-------------------------ADDED FILES--------------------------------";
foreach (keys %hash2){
    print "added $_\n" unless exists $hash1{$_};
}

print "-------------------------MISSING FILES--------------------------------";
foreach (keys %hash1){
    print "Missing $_\n" unless exists $hash2{$_}; 
}

print "-------------------------Different permissions--------------------------------";

foreach my $key2 ( keys %hash2 ) {
    unless ( exists $hash1{$key2} ) { next; };
    if (join(",", sort @{ $hash1{$_}})
      eq join(",", sort @{ $hash2{$_}}) ){
      }
      else{
          print "value is different";
      }
}

Issue is when keys are same.This for each loop doesn't work well.I want to print like this:

FileName: File Attributes Before : File Attributes after
abc.txt: '0744','0': 0766','0'

Please help

2
I'm not sure, if I understand correctly, but your problem is to print the result, in case your arrays are different? I mean, something like: print "$key2: ".join(",", sort @{ $hash1{$key2}}.": ".join(",", sort @{ $hash2{$key2}}."\n" ... or do you have a different question? - user3112922
Currently my control is never going to else block.So my problem is how to compare the values of two hashes(here value is of the form array) if key is equal. and how to print it if values are different? - Sammidbest
You could compare them using the smartmatch operator: $hash1{$key2} ~~ $hash2{$key2} : ) See perldoc.perl.org/perlop.html#Smartmatch-Operator ... And then just print themn by using print "$key2: ".join(",", @{ $hash1{$key2}}).": ".join(",", @{ $hash2{$key2}})."\n" - user3112922

2 Answers

1
votes

Your code didn't work, because you defined my $key2 in your foreach-loop, which leaves $_ as an empty value.

Also you don't need to join the hashes. Try the smartmatch operator on array values, its more efficient since you only need to do the join, when you want to have an output.

foreach my $key2 ( keys %hash2 ) {
    unless ( exists $hash1{$key2} ) { next; };
    unless ( $hash1{$key2} ~~ $hash2{ $key2 } )
    {
        print "$key2: ".join(",", @{ $hash1{$key2}}).": ".join(",", @{ $hash2{$key2}})."\n"
    }
}
0
votes

Change

foreach my $key2 ( keys %hash2 ) {
    unless ( exists $hash1{$key2} ) { next; };
    if (join(",", sort @{ $hash1{$_}})
      eq join(",", sort @{ $hash2{$_}}) ){
      }
      else{
          print "value is different";
      }
}

to

foreach my $key2 ( keys %hash2 ) {
    next unless ( exists $hash1{$key2} );
    my $val1 = join(",", sort @{ $hash1{$key2} });
    my $val2 = join(",", sort @{ $hash2{$key2} });
    if ($val1 eq $val2) {
        # values are same
    }
    else {
        print "$key2 $val1 $val2\n";
    }
}

and try again.