I have a hash array with a YAML, which was taken from a linux command. I have another hash array, with the same YAML set, but with different values, by the same command, which was run at a later time.
Eg.
content.none:
bytes: 31046
content.image.gif:
bytes: 0
and
content.none:
bytes: 31050
content.image.gif:
bytes: 0
Now, I am looking for a math operation between the values. I am looking for an output
content.none:
bytes: 4
content.image.gif:
bytes: 0
which is the result of math between the corresponding values in the hash.
I tried iterating and doing diff, but it looks like a cumulative output.
%host_stat_new=New stats
%host_stat_old=Old stats (taken from stats.yml, which contains old data)
while (true){
open my $FH1, ">stats.yml" or die "cannot write to stat file because $!\n";
foreach my $line4 (keys %host_stat_new){
print $FH1 "$line4:\n";
foreach my $line5 (keys %{$host_stat_new{$line4}}) {
print $FH1 " $line5: \n";
foreach my $line6 (keys %{$host_stat_new{$line4}{$line5}}){
my $diff1 = $host_stat_new{$line4}{$line5}{$line6};
my $diff2 = $host_stat_old{$line4}{$line5}{$line6};
$math=$diff1-$diff2;
#$host_stat1{$line4}{$line5}{$line6} = $math;
$host_stat_new{$line4}{$line5}{$line6} = $math;
print $FH1 " $line6: $host_stat_new{$line4}{$line5}{$line6}\n";
}
}
}
}
What am I doing wrong here? Is there any module that can do this?
Just use some good ole recursion to get the diff. This function assumes that the data structures are identical, could add functionality to confirm that:
use YAML;
use strict;
use warnings;
my $str1 = <<YAML_STRING1;
content.none:
bytes: 31046
content.image.gif:
bytes: 0
YAML_STRING1
my $str2 = <<YAML_STRING2;
content.none:
bytes: 31050
content.image.gif:
bytes: 0
YAML_STRING2
my $data1 = Load($str1);
my $data2 = Load($str2);
my $diff = diff_recurse($data2, $data1);
print Dump($diff);
sub diff_recurse {
my ($str1, $str2) = @_;
my $diff;
if ('HASH' eq ref $str1) {
$diff = {};
for my $key (keys %$str1) {
$diff->{$key} = diff_recurse($str1->{$key}, $str2->{$key});
}
} elsif ('ARRAY' eq ref $str1) {
$diff = [];
for my $i (0..$#$str1) {
$diff->[$i] = diff_recurse($str1->[$i], $str2->[$i]);
}
} elsif (my $unknown = ref $str1) {
die "Unknown type $unknown\n";
} elsif ($str1 =~ /^[\d\.]+$/) {
$diff = $str1 - $str2;
} else {
$diff = $str1;
}
return $diff;
}
Outputs
---
content.image.gif:
bytes: 0
content.none:
bytes: 4