1752492 Members
5255 Online
108788 Solutions
New Discussion юеВ

Perl;

 
SOLVED
Go to solution
Hakki Aydin Ucar
Honored Contributor

Perl;

Hi the following Perl snippet use Text::CSV; and according to time stamps add some columns vaule.

while () {
next if ($. == 1);
if ($csv->parse($_)) {
my @columns = $csv->fields();
#Get HR MIN SEC by splitting the time_stamp in column 1
my $col = substr ( $columns[1],0,8 );
my @col = split (/:/,$col);
my $hour = $col[0];
my $minute = $col[1];
my $secs = $col[2];

if (( $hour == 23 ) && ( $columns[4] eq 'VERSOSIP.2W.900.900' )) {
my $calcs += $columns[6];
print "Time: $columns[1]\tROUTE_CLLI: $columns[4]\t$columns[6]\n";
}
} else {
my $err = $csv->error_input;
print "Failed to parse line: $err";
}
}

it prints out the rows like this:
Time: 23:00 ROUTE_CLLI: VERSOSIP.2W.900.900 130
Time: 23:30 ROUTE_CLLI: VERSOSIP.2W.900.900 127

But I wanted it have results added like this;
Time: 23:30 ROUTE_CLLI: VERSOSIP.2W.900.900 257

How can I achieve this OR which function you think is able to do it ?


8 REPLIES 8
James R. Ferguson
Acclaimed Contributor

Re: Perl;

Hi:

You are printing every line of input rather than a line representing a summation.

Instead of:

print "Time: $columns[1]\tROUTE_CLLI: $columns[4]\t$columns[6]\n";

...you want something like:

print "Time: $columns[1]\tROUTE_CLLI: $columns[4]\t$calc\n";

..and you want this to occur after the read loop (while...) has ended.

Regards!

...JRF...
Hakki Aydin Ucar
Honored Contributor

Re: Perl;

Hi James,
>print "Time: $columns[1]\tROUTE_CLLI: $columns[4]\t$calc\n";

..and you want this to occur after the read loop (while...) has ended.

Yes, but my method only result the what they read per line.Not summary.

it can either be inside while loop OR loop has ended.

Thanks.
Hakki

James R. Ferguson
Acclaimed Contributor

Re: Perl;

Hi (again) Hakki:

> Yes, but my method only result the what they read per line.Not summary. it can either be inside while loop OR loop has ended.

So I presume you want "running totals". Then change:

print "Time: $columns[1]\tROUTE_CLLI: $columns[4]\t$columns[6]\n"

...to:

print "Time: $columns[1]\tROUTE_CLLI: $columns[4]\t$calc[6]\n"

Regards!

...JRF...
James R. Ferguson
Acclaimed Contributor

Re: Perl;

Hi (again) Hakki:

Oops, I hit submit too soon.

> Yes, but my method only result the what they read per line.Not summary. it can either be inside while loop OR loop has ended.

So I presume you want "running totals". Then change:

print "Time: $columns[1]\tROUTE_CLLI: $columns[4]\t$columns[6]\n"

...to:

print "Time: $columns[1]\tROUTE_CLLI: $columns[4]\t$calc\n"

Regards!

...JRF...
Hakki Aydin Ucar
Honored Contributor

Re: Perl;

Hi James,

print "Time: $columns[1]\tROUTE_CLLI: $columns[4]\t$calc\n" ;

still prints the result one line at a time wheras I want the total in loop;
it prints below:

Time: 23:00 ROUTE_CLLI: VERSOSIP.2W.900.900 130
23 00
Time: 23:30 ROUTE_CLLI: VERSOSIP.2W.900.900 127
23 30

I want:
Time: 23:30 ROUTE_CLLI: VERSOSIP.2W.900.900 257

James R. Ferguson
Acclaimed Contributor
Solution

Re: Perl;

Hi (again):

> still prints the result one line at a time wheras I want the total in loop;

Look at this test-case:

# cat ./mytest
#!/usr/bin/perl
use strict;
use warnings;
my ( $calc, @values );
while () {
@values = split;
if ($values[1] =~ m{23:}) {
$calc += $values[4];
print "Time: $values[1] ROUTE_CCLI: VERSOSIP.2W.900.900 $calc\n";
}
}
print "LAST: $values[1] ROUTE_CCLI: VERSOSIP.2W.900.900 $calc\n";
1;
__DATA__
Time: 23:00 ROUTE_CLLI: VERSOSIP.2W.900.900 130
Time: 23:10 ROUTE_CLLI: VERSOSIP.2W.900.900 100
Time: 23:20 ROUTE_CLLI: VERSOSIP.2W.900.900 100
Time: 23:30 ROUTE_CLLI: VERSOSIP.2W.900.900 127


...now run as './mytest' and you will see:

Time: 23:00 ROUTE_CCLI: VERSOSIP.2W.900.900 130
Time: 23:10 ROUTE_CCLI: VERSOSIP.2W.900.900 230
Time: 23:20 ROUTE_CCLI: VERSOSIP.2W.900.900 330
Time: 23:30 ROUTE_CCLI: VERSOSIP.2W.900.900 457
LAST: 23:30 ROUTE_CCLI: VERSOSIP.2W.900.900 457

Regards!

...JRF...
Hakki Aydin Ucar
Honored Contributor

Re: Perl;

Hi James,

Your code is working great. Probably my module in use needs another type of definition OR I did a logical mistake something else.

Regards!
Hakki Aydin Ucar
Honored Contributor

Re: Perl;

Solution is to declare a global outside the loop before, working code is:

# cat test3
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;
my ( $calc );
my $file = 'pnm_om.05_04_2010.0030.ISBLTUGS01D.OT.CSV';

my $csv = Text::CSV->new();

open (CSV, "<", $file) or die $!;

while () {
next if ($. == 1);
if ($csv->parse($_)) {
my @columns = $csv->fields();
#Get HR MIN SEC by splitting the time_stamp in column 1
my $col = substr ( $columns[1],0,8 );
my @col = split (/:/,$col);
my $hour = $col[0];
my $minute = $col[1];
my $secs = $col[2];

if (( $hour == 20 ) && ( $columns[4] eq 'VERSOSIP.2W.1500.1500' )) {
$calc += $columns[6];
print "Time: $columns[1]\tROUTE_CLLI: $columns[4]\t$calc\n";
print "$hour $minute\n";
}
} else {
my $err = $csv->error_input;
print "Failed to parse line: $err";
}
}
close CSV;


Thanks again James!