tags:

views:

112

answers:

3

I'm really new to Perl, but I want to basically read in a file to get some data out of it. I want to parse this data into an array. Why an array? Because, I want to use the data to generate an graph (bar or pie of the data).

Here's my code for Perl so far:

#!/usr/bin/perl -w
use warnings;

#Creating an array 
my @cpu_util;

#Creating a test file to read data from
my $file = "test.txt";      
#Opening the while      
open(DATA, $file) || die "Can't open $file: $!\n";

#Looping through the end of the file
while (<DATA>) 
{
if (/(\w+)\s+\d+\s+(\d+)\.(\d+)\%/){ #Getting only the "processes"
chomp;
push @cpu_util, split /\t/; #I was hoping this would split the data at the tabs
}
}

close ($file);

foreach $value (@cpu_util) {
print $value . "\n";
}

Here's the file that I am reading in (test.txt):

=========================================

CPU Utilization 

=========================================

Name      CPU Time     CPU Usage    

-----------------------------------------

System                7962         3.00% 

Adobe Photoshop       6783         0.19% 

MSN Messenger         4490         0.01% 

Google Chrome         8783         0.02% 

Idle                   120        94.00% 

=========================================

However, what I notice is that I successfully populate the array, but it doesn't split the tabs and give me a multidimensional array. I don't really care about the CPU time field, but I do want the CPU Usage, So I want to print an XY chart with Y-axis having the CPU-usage and x-axis, the process name.

I was hoping to have an array "cpu_util" and have cpu_util[0][0] = System and cpu_util[0][1] = 3.00. Is this even possible? I thought the split /\/t\ would take care of it, but apparently I was mistaken ...

+6  A: 

I think you want a hash there. The key would be the CPU name and the value would be the percent use. You're almost there. After a successful match, use the captures ($1 and $2) to populate the hash:

my %cpu_util;   
while (<DATA>) 
    {
    if (/(.*?)\s+\d+\s+(\d+\.\d+)\%/){ #Getting only the "processes"
        $cpu_util{ $1 } = $2;
        }
    }

use Data::Dumper;   
print Dumper( \%cpu_util );

Your data structure should be much easier to use then:

$VAR1 = {
          'Google Chrome' => '0.02',
          'System' => '3.00',
          'Adobe Photoshop' => '0.19',
          'Idle' => '94.00',
          'MSN Messenger' => '0.01'
        };

Your split probably doesn't work because there aren't tabs there. It's not really they way to go anyway.

brian d foy
Thanks Brian, that did the trick. I'm now going to try and look up, how to graph this data. I did look into the $1 and $2 usage in terms of Perl, but it still doesn't make much sense to me. Could you perhaps point me to a place where its explained well? I don't understand what exactly is happening at:>$cpu_util{ $1 } = $2;
c0d3rs
_Learning Perl_ is a good place to start. :)
brian d foy
A: 

[wrong answer redacted]

ihateme
Did you bother to even look at your output?
brian d foy
obviously not.. its late and i dont feel like fixing this now.. someone please do the the honors.. thanks..
ihateme
Well, you can delete wrong answers. I've already correctly did what you were trying to do.
brian d foy
there is more than one way to do it mr.foy :) you should know that.. let me fix this...
ihateme
Thanks for your reply, but I think I'm going to go with the hash for now. I will refer back if it doesn't work with graphing ...
c0d3rs
There may be more than one way to do it, but most of them are wrong. You can, however, edit your answers so you don't have to provide a new one. You can delete this one, too.
brian d foy
A: 

Here is your code fixed ihateme:

use Data::Dumper;
#use strict;

#Creating an array
my @cpu_util;

#Creating a test file to read data from
my $file = "bar.txt";
#Opening the while
open(DATA, $file) || die "Can't open $file: $!\n";

#Looping through the end of the file
while (<DATA>)
{
  if (/(\w+)\s+\d+\s+(\d+)\.(\d+)\%/)
  {
    chomp;
    my ( $name, $cpuusage, @rest  ) = split ( /\s+\d+\s+(\d+\.\d+)\%/);
    push @cpu_util, [$name, $cpuusage ];
  }

}
close $file;

print Dumper(\@cpu_util);
$ref = $cpu_util[0];  # this will set the reference to the first array
$ref -> [2]; # this will return the 3rd value
print Dumper ($ref -> [1]);


 $VAR1 = [
      [
        'System',
        '3.00'
      ],
      [
        'Adobe Photoshop',
        '0.19'
      ],
      [
        'MSN Messenger',
        '0.01'
      ],
      [
        'Google Chrome',
        '0.02'
      ],
      [
        'Idle',
        '94.00'
      ]
    ];

$VAR1 = '3.00';

ihateme2
You're doing a bit too much work there. You really only need one match. Grab the stuff you need in the first match so you don't have to do the second.
brian d foy