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

Hi, Here is my input file(i.e gen_machines_data.txt) which as follows:
{asf192lin1 C 0/8 0 0 0 4503 16 2922 44316 1} {asf256lin10 + 2/16 15 0 0 4641 16 2926 194108 0} {cad192lin1 C 0/12 2 0 0 1432 12 3397 179605 0} {cas256lin1 C 0/12 50 0 56 3992 12 3397 165099 0} {cas192lin11 C 0/12 50 0 56 3992 12 3397 165099 0} {dsf192lin6 + 0/16 0 0 0 4751 16 2930 179123 0}
My code:
open my $f,"<gen_machines_data.txt" or die $!; my($slots_used,$slots_free); while(<$f>) { #print $_; $slots_used += (split(/\s+/,$_))[3]; $slots_free++; } close $f; print "total slots used:$slots_used\n"; print "total slots free:$slots_free\n";
My query:
1.How to total the third column numerator and denominator values and store the numerator total separately and denominator values separately for the same starting name(note:from column one we should consider only first three letter for each row) of the rows from the column 1 using perl.
For example:
In the above input file there are two rows which starts with asf and some other rows starts with dsf and cas.
Now the thing is how can i give the row name starting three letters by standard input and how can i total the third column values for numerator and denominator and store it separately.
code which i had tried using perl:
open my $f,"<gen_machines_data.txt" or die $!; my($slots_used,$slots_free); while(<$f>) { #print $_; $slots_used += (split(/\s+/,$_))[3]; $slots_free++; } close $f; print "total slots used:$slots_used\n"; print "total slots free:$slots_free\n";
But the above code gives me wrong output.Kindly help me to revamp my perl script as per my requirements.
Expected output:
script execution:perl check.pl
print statement:print the name from column1
if i give column name as asf => this i should give by <STDIN> at the time of execution
Now it should give output as like follows:
Slots Used:2
Slots free:24

Replies are listed 'Best First'.
Re: How to add the rows by its similar row names using perl?
by huck (Prior) on May 05, 2017 at 05:46 UTC

    Lets see.

    perl uses what is called a zero-origin, columns are numbered starting at zero, ie 0,1,2,3 so what you considered the 3rd column via $slots_used += (split(/\s+/,$_))[3]; is actualy the 4th column.

    when you split via  split(/\s+/,$_) you only split on whitespaces, but it seems you also need to split column 3 by the slash to get what you want.

    Just out of cleanness you probably should have chomped your input to get rid of the newline

    And it probably makes sense to get rid of the squiggly braces too

    use strict; use warnings; my %namesum; while (my $line=<DATA>) { chomp $line; next unless $line; $line=~s/[\{\}]//g; my @parts=split(/\s+/,$line); my ($slots_used,$slots_free)=split('/',$parts[2]); my $name=substr($parts[0],0,3); $namesum{$name}[0]+=$slots_used; $namesum{$name}[1]+=$slots_free; } for my $key (sort keys %namesum){ print "\nname:".$key."\n"; print "total slots used:".$namesum{$key}[0]."\n"; print "total slots free:".$namesum{$key}[1]."\n"; } __DATA__ {asf192lin1 C 0/8 0 0 0 4503 16 2922 44316 1} {asf256lin10 + 2/16 15 0 0 4641 16 2926 194108 0} {cad192lin1 C 0/12 2 0 0 1432 12 3397 179605 0} {cas256lin1 C 0/12 50 0 56 3992 12 3397 165099 0} {cas192lin11 C 0/12 50 0 56 3992 12 3397 165099 0} {dsf192lin6 + 0/16 0 0 0 4751 16 2930 179123 0}
    result
    name:asf total slots used:2 total slots free:24 name:cad total slots used:0 total slots free:12 name:cas total slots used:0 total slots free:24 name:dsf total slots used:0 total slots free:16
    So tell the truth now, was this course homework?

Re: How to add the rows by its similar row names using perl?
by kcott (Archbishop) on May 05, 2017 at 07:42 UTC

    G'day gopikavi,

    Welcome to the Monastery.

    I see ++huck has pointed out your indexing error and usage of a hash. Here's an alternative method for capturing the data:

    #!/usr/bin/env perl -l use strict; use warnings; my %slot; my $re = qr{([a-z]{3}).*?(\d+)/(\d+)}; while (<DATA>) { if (/$re/) { $slot{$1}{used} += $2; $slot{$1}{free} += $3; } } print "$_: @{$slot{$_}}{qw{used free}}" for sort keys %slot; __DATA__ {asf192lin1 C 0/8 0 0 0 4503 16 2922 44316 1} {asf256lin10 + 2/16 15 0 0 4641 16 2926 194108 0} {cad192lin1 C 0/12 2 0 0 1432 12 3397 179605 0} {cas256lin1 C 0/12 50 0 56 3992 12 3397 165099 0} {cas192lin11 C 0/12 50 0 56 3992 12 3397 165099 0} {dsf192lin6 + 0/16 0 0 0 4751 16 2930 179123 0}

    Output:

    asf: 2 24 cad: 0 12 cas: 0 24 dsf: 0 16

    — Ken