Kay
Kay

Reputation: 2077

How to compute Cumulative values in Shell?

I would like to compute cumulative values from the below data file and writing them into columns after inserting a serial number.

ifile.txt
1 2 3 2 3 1 4 5 1 
3 4 5 2 3 4 1 3 1 
1 3 2 3 2 4 1 2 4 ...............

Where ifile.txt has 3 rows and 9 columns in this example. Desire output:

ofile.txt
1  1   3   1
2  3   7   4
3  6   12  6
4  8   14  9
5  11  17  11
6  12  21  15
7  16  22  16
8  21  25  18
9  22  26  22
.  
.  
.  

Here first column is used for the serial number. So what I did is: I first converted into columns using

awk '{ 
for (i=1; i<=NF; i++)  {
    a[NR,i] = $i
     }
}
NF>p { p = NF }
END {    
for(j=1; j<=p; j++) {
    str=a[1,j]
    for(i=2; i<=NR; i++){
        str=str" "a[i,j];
    }
    print str
    }
 }' ifile.txt > ifile1.txt

Then I use awk

awk '{print m1=$1+m1, m2=$2+m2, m3=$3+m3}' ifile1.txt > ofile.txt

I can't proceed for the next step i.e. to insert a column of serial number. Also I can't make it for arbitrary columns and rows.

Upvotes: 1

Views: 938

Answers (3)

Shravan Yadav
Shravan Yadav

Reputation: 1317

for column of serial number

awk '{print i=i+1,m1=$1+m1, m2=$2+m2, m3=$3+m3}' ifile1.txt > ofile.txt

and for complete solution of your logic

awk '{for(i=1;i<=NF;i++){if(i>1)$i=$i+$(i-1);f[i]=f[i]" "$i}if(NF>n)n=NF}END{for(i=1;i<=n;i++)print i,f[i]}'

Upvotes: 3

Robin Hsu
Robin Hsu

Reputation: 4504

A better way to produce serial numbers in the header:

First, forget the serial numbers, just focus on the generation of the results. Say you manage to get a temporal results in tmp_ofile.txt, without serial numbers.

Then, just do

cat -n tmp_ofile.txt > ofile.txt

You will get the serial number header.

Upvotes: 1

choroba
choroba

Reputation: 241938

Perl to the rescue!

perl -lane '
           $l = 0;
           push @s, [ map { $l = $l + $F[$_] } 0 .. $#F];
           }{
           for $i (0 .. $#{$s[0]}) {
               print join " ", $i + 1, map $s[$_][$i], 0 .. $#s;
           }' < ifile.txt > ofile.txt
  • -l adds newlines to print
  • -a splits each line into the @F array
  • -n reads the input line by line
  • $l is the "last sum" for each row
  • @s is the array of arrays that keeps the sums

Upvotes: 2

Related Questions