tags:

views:

442

answers:

4

Hi I have a file with following data:

1==0==2
5==3==2
7==1==0

how to add the numerical value column wise. I need to summarize and print it like

1==0==2
5==3==2
7==1==0
13==4==4   * summation column wise (This is what I want to calculate using perl)

I guess you have misunderstood my question. I have edited my question again by ... i meant I have many such column in the table 13==4==4 is the summation column wise which I want add to my file.

I was able to do it for first column only but i need to learn how to for all the other columns as well.

my code:

#!/usr/bin/perl

use strict;
use warnings;

open (TEMPTABLE,"temp_data") or die "Cannot open file\n";

my @temp_table_data=< TEMPTABLE > ;
chomp @temp_table_data;

my $total_sum;
for(my $i=0;$i<=$#temp_table_data;$i++)
{
print "$temp_table_data[$i]\n";
my @col=split('==',$temp_table_data[$i]);
for(my $m=0;$m<1;$m++)
{
$total_sum+=$col[$m];
}    
}
print "$total_sum\n";

OUTPUT:
1==0==2
5==3==2
7==1==0
13

I don't want to sum ROW but COLUMN.

+3  A: 
  1. Create a variable that can hold an array
  2. Go through each line and sequentially add the values to your array
  3. Repeat until done.
innaM
thanks mani but i was not able to code as per your description.
Suren
+4  A: 

What you're trying to do does not seem that complex. If '==' is your column delimiter:

use strict;
use warnings;
use List::MoreUtils qw<pairwise>;

our ( $a, $b );

my @totals;

while ( my $record = <DATA> ) { 
    chomp $record;
    my @data = split /==/, $record;
    push @totals, ( 0 ) x ( @data - @totals ) if @data > @totals;
    pairwise { $a += $b } @totals, @data;
 }
__DATA__
1==0==2
5==3==2
7==1==0
13==4==4
Axeman
+1 for pairwise.
Sinan Ünür
I wanted to to make it a self-modifying void call to pairwise: `pairwise { $a += $b } @totals, ...` but it won't let me.
Axeman
@Axeman Hmmm ... If you add `my @totals = (0) x 3;` it will let you use it in void context. I am not sure if there is a good reason for the autovivified value not to be modifiable or if it is a bug.
Sinan Ünür
@Sinan Ünür: Got it to work. I'm thinking that it probably runs quicker with the in-place increment.
Axeman
Axeman: That `push` is a nice way of avoiding hardcoding the number of columns. I would vote your answer up again if I could.
Sinan Ünür
+1  A: 

Here's my entry

use strict;
use warnings;

my @LineTotalsArray;

while (my $line = <DATA>) {
   print $line;
   chomp $line;

   my $index=0;
   for my $val ( split /==/, $line ) {
      $LineTotalsArray[ $index++ ] += $val;
   }
}

print join('==', @LineTotalsArray), "\n";

__DATA__
1==0==2
5==3==2
7==1==0
lexu
Thanx Lexu. Your script works. Thanks again.
Suren
Your welcome. Please note that I implemented Manni's suggestion ..
lexu
Can you please explain me what $LineTotalsArray->[$index++]+=$val; means and what its doing?
Suren
*LineTotalsArray* is an array that holds the total per *column*. *index* is a helper to traverse over all the numbers (held in $val) in you input line. *+= adds* the value to the right to the value to the left.
lexu
@lexu It would have been clearer if you had used an actual array rather than array reference *and* some whitespace in your formatting.
Sinan Ünür
@lexu, thanx I understood it now.
Suren
+4  A: 

People are trying to be pretty clever in their answers. I think it's much more clear what's going on without the tricks. You certainly don't need pairwise, and I think in this case it makes the code harder to follow. This is simple with just built-in Perl:

my @sums;

while( <DATA> ) {
   my @summands = split /==/;

   foreach my $i ( 0 .. $#summands ) {
   $sums[$i] += $summands[$i];
   }
}

print "Sums are (@sums)\n";

__END__
1==0==2
5==3==2
7==1==0
brian d foy
@Brian, your script works very nicely as well, Thanks a lot for the codes.
Suren