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

I have the iostat -x data which I have parsed and converted into XML using Test::Parser::Iostat. I need the parsed output to create a graph using GD else GD::Graph. I have created a hash with the keys and all the values associated with. But to use a GD::Graph I need to convert this hash to array of arrays to generate a graph. How do I do this else is it possible to utilize this hash to generate a Graph?

The code is #!/usr/bin/perl use strict; use warnings; use File::Slurp; use Data::Dumper; my %graph_point_hash; my @report_graph_point = `sed -e 's/data//g' -e 's/[\<\/\>]//g' -e 's/ +^ *//' -e 's/* \$//' -e '/^\$/d' -e '1d;\$d' $ARGV[0]`; my @split_graph_points; foreach (@report_graph_point) { @split_graph_points = split (' ', $_); foreach my $graph_point (@split_graph_points) { $graph_point =~ s/"//g; my ($key, $val) = split ("=", $graph_point); push (@{$graph_point_hash{$key}}, "$val"); } #foreach loop ends here } #foreach loop ends here print Dumper \%graph_point_hash; XML file is <iostat> <data avgqu="0" avgrq="0" await="0" device="sdb" elapsed_time="0" r= +"0" rmb="0" rrqm="0" svctm="0" util="0" w="0" wmb="0" wrqm="0" /> <data avgqu="0" avgrq="0" await="0" device="sda" elapsed_time="0" r= +"0" rmb="0" rrqm="0" svctm="0" util="0" w="0" wmb="0" wrqm="0" /> <data avgqu="0.00" avgrq="0.00" await="0.00" device="sdb" elapsed_ti +me="1" r="0.00" rmb="0.00" rrqm="0.00" svctm="0.00" util="0.00" w="0. +00" wmb="0.00" wrqm="0.00" /> <data avgqu="0.00" avgrq="58.91" await="0.09" device="sda" elapsed_t +ime="1" r="0.00" rmb="0.00" rrqm="0.00" svctm="0.09" util="0.05" w="5 +.50" wmb="324.00" wrqm="35.00" /> <data avgqu="0.00" avgrq="0.00" await="0.00" device="sdb" elapsed_ti +me="2" r="0.00" rmb="0.00" rrqm="0.00" svctm="0.00" util="0.00" w="0. +00" wmb="0.00" wrqm="0.00" /> THE OUTPUT IS $VAR1 = { 'w' => [ '0', '0', '0.00', '5.50', '0.00', '2.50', '0.00', '489.50', '0.00', '0.00', '0.00', '0.00', '0.00', '242.00', '0.00', '0.00', '0.00', '5.50', '0.00', '4.00',

Replies are listed 'Best First'.
Re: I need to create a graph from a hash using GD else GD::Graph
by Laurent_R (Canon) on Sep 10, 2013 at 10:40 UTC

    You should probably use a module to read your XML, but if you really want to do it manually and get an array of arrays, you might want to follow the lines of this session under the Perl debugger:

    DB<54> $c = '<data avgqu="0" avgrq="0" await="0" device="sdb" elapse +d_time="0" r="0" rmb="0" rrqm="0" svctm="0" util="0" w="0" wmb="0" wr +qm="0" />'; DB<55> push @AoA, [$c =~ /"([.\d]+)"/g]; DB<56> $c = '<data avgqu="0.00" avgrq="58.91" await="0.09" device="s +da" elapsed_time="1" r="0.00" rmb="0.00" rrqm="0.00" svctm="0.09" uti +l="0.05" w="5.50" wmb="324.00" wrqm="35.00" />'; DB<57> push @AoA, [$c =~ /"([.\d]+)"/g]; DB<58> $c = '<data avgqu="0.00" avgrq="58.91" await="0.09" device="s +da" elapsed_time="1" r="0.00" rmb="0.00" rrqm="0.00" svctm="0.09" uti +l="0.05" w="8.50" wmb="332.00" wrqm="27.00" />'; DB<59> push @AoA, [$c =~ /"([.\d]+)"/g];

    This gives you the following structure:

    But I am not sure that this is what you are looking for, you haven't given enough details.

      I tried using XML modules but the parsed output gives only iostat as the tag and rest as the data which I need to remove. The original iostat data parsed to XML is in the form

      <iostat> <data avgqu="0" avgrq="0" await="0" device="sdb" elapsed_time="0" r= +"0" rmb="0" rrqm="0" svctm="0" util="0" w="0" wmb="0" wrqm="0" /> <data avgqu="0" avgrq="0" await="0" device="sda" elapsed_time="0" r= +"0" rmb="0" rrqm="0" svctm="0" util="0" w="0" wmb="0" wrqm="0" /> .........................(truncated) </iostat>
      Here I need to remove data and other special characters to get the data. From this data I need to draw a graph. For Drawing the Graph I need to use GD::Graph module which requires to use array of arrays. I am able to build a hash from the XML file which I have provided earlier but I am not able to convert it to array of arrays. Is it also possible to covert the hash to Excel, if yes how do I do that?

        The Test::Parser::Iostat has a data method which provides a hash, no need to parse the XML. This example plots a histogram of util against elapsed time for sda2 from a file created with iostat sda2 -x 1 10 > iostat.txt.

        #!/usr/bin/perl use strict; use Test::Parser::Iostat; use GD::Graph::bars; my $parser = new Test::Parser::Iostat(); open IN,'iostat.txt' or die "$!"; $parser->parse(\*IN) or die $parser->error(), "\n"; my $hash = $parser->data(); # create plot data my @plot=([],[]); for my $ar (@{$hash->{'iostat'}{'data'}}){ if ($ar->{'device'} eq 'sda2'){ push @plot[0],$ar->{'elapsed_time'}; push @plot[1],$ar->{'util'}; } } # create graph my $graph = GD::Graph::bars->new(400, 300); $graph->set( x_label => 'Elapsed time', y_label => 'Util', title => 'sda2 util', y_max_value => 100, ) or die $graph->error; my $gd = $graph->plot(\@plot) or die $graph->error; open(IMG, '>iostat.gif') or die $!; binmode IMG; print IMG $gd->gif;
        poj

        The hash that you extracted really contains only one linear array, which is probably not suitable for what you want to do. On the other hand, I provided you with a means to get an array of arrays, which is what you asked for in the first place, did you look at the AoA I obtained? Is it suitable for your purpose? As for GD::xxx, I do not know these modules nand can't help further.