http://www.perlmonks.org?node_id=946008


in reply to Counting devices types, device sizes and number of devices.

Dear perl514,

sounds like you got a good concept of solving your problem. Please add your sourcecode to the questions if possible for better help.

I'd walk through the lines using while (<$fh>) and split each line at \t which returns an array of each line's information.

Understanding might be easier if you print out the split result array using join or Data::Dumper until your script is working.

If all you need is this output, you may use a trick to avoid using references (which isn't that easy for Perl beginners) by using a hash and the full text part ("Total Number of $split_result[4] Devices of $split_result[7]MB") as the key. The "++" operator easily adds one for each device found matching that key.

The conversion of MB's to other units may be done using a if/elsif/else block or a CPAN module like Format::Human::Bytes.

Replies are listed 'Best First'.
Re^2: Counting devices types, device sizes and number of devices.
by perl514 (Pilgrim) on Jan 03, 2012 at 07:36 UTC

    Hi Sewi,

    Thanks for the reply.

    I was planning to first use an array and then pass the elements of the array to a hash...Came out with very very basic stuff like this:

    #!/usr/bin/perl use warnings; use strict; my $command = `symdev -sid 1234 list -noport -noreserve|find /I "not v +isible"`; my @cmdline = split (/\n/, $command); my @chgcmdline = @cmdline[5,8]; print "@chgcmdline\n";

    But got stuck after this. Tried going through the node I have mentioned earlier and figuring out. The  symdev -sid 1234 list -noport -noreserve|find /I "not visible" is the command that gives the output mentioned in my post.

    BTW - I am using Strawberry Perl that came bundled with Padre IDE and I do sometimes use Padre. Awesome IDE. Mr. Gabor did a great thing by pre bundling a lot of modules. Neat stuff :)

    Perlpetually Indebted To PerlMonks

      The my $command = `symdev... doesn't do what you might think. It puts back one line of the symdev output in $command. If you split one line by \n, one item remains (the line without line ending), so your 5,8 are empty/undef because the array simply doesn't have that many items.

      Try this instead:

      open my $fh, '-|', 'symdev -sid 1234 list -noport -noreserve|find /I " +not visible"'; while (<$fh>) { chomp; my @line = split(/\t/); [...]

      The sample above runs the symdev (I'm a little bit unsure about the piping 3-argument-open, try out open my $fh, 'symdev -sid 1234 list -noport -noreserve|find /I "not visible" |'; (notice the final | after the command if it doesn't work) and offers it's output via filehandle $fh.

      The while loop reads the output line by line presenting every single line in the default variable $_ for one loop run.

      Read chomp's documentation to see what it does. split also uses the default variable if none specified and returns the columns of the line.

      I suggested a text hash key instead of the hash tree shown in another answer to your original post because you simple don't need the detailed data in your sample and keeping things simpler might be better for the moment.

      Another tip for you...With Perl, you can specify indicies from either side of an array or list. Some of your data lines have 8 some 9 things. So to get the 6th thing and the last thing, do it like this.. Main point is that by using negative index, you can get the last thing even if number of things varies. I think your actual data is tab separated? if so, then adjust accordingly.
      while (<DATA>) { my ($desc,$MB) = (split)[5,-1]; print "$desc $MB\n"; } =prints 2-Way 3 2-Way 3 2-Way 3 RAID-5 8632 RAID-5 8632 RAID-5 34526 2-Way 34526 2-Way 34526 2-Way 69052 RAID-5 34526 RAID-5 34526 RAID-5 69052 RAID-5 69052 BCV+R5 34526 BCV+R5 34526
      The index of -1 means "last item", -2 would mean next to last one, etc.