Shell script - precent value

Hello,

I have example data like below:

     39 ,2012/01,0
     22 ,2012/02,0
      2 ,2012/02,1
     23 ,2012/03,0
      3 ,2012/03,1
     16 ,2012/04,0
      2 ,2012/04,1
      8 ,2012/05,0
      2 ,2012/05,1

It is possible (awk, sed, bash) to calculate output like below (second value is a percent):

2012/01;100
2012/02;91,666 /* quick explanation: 22/(22+2) * 100 */
2012/03;88,46 /* 23/(23+3) * 100 */
2012/04;88,88 /* 16/(16+2) * 100 */
2012/05;80,00 /* 8/(8+2) * 100 */

?

To be honest: I dont know how to start ;/

Thank you in advance for any tips.

Best regards

This assumes that the value in the first column is always greater than zero:

awk -F , '
    $2 != l  && NR > 1 {
        printf( "%s; %.3f\n", l, (f/sum) * 100 );
        f = sum = $1;
        l = $2;
        next;
    }
    {
        sum += $1;
        l = $2;
    }
    END {
        if( sum )
            printf( "%s; %.3f\n", l, (f/sum) * 100 );
    }
' input-file

Hello agama,

In every line first column has value greater than 0 or it won't appear.

And here is an issue related with above:

2012/01;0

this should be

2012/01;100

since there are no values like

x ,2012/01,1

Now I have to understand your script - later I will try fix this.

Thank you for quick help !

Best regards,

That can be quickly corrected by changing

    $2 != l  && NR > 1 {
        printf( "%s; %.3f\n", l, (f/sum) * 100 );

to

    $2 != l {
        if( sum )
            printf( "%s; %.3f\n", l, (f/sum) * 100 );

Hello,

awk -F , '
    $2 != l  && NR > 1 {
        if ( sum )
        printf( "%s; %.3f\n", l, (f/sum) * 100 );
        f = sum = $1;
        l = $2;
        next;
    }
    {
        sum += $1;
        l = $2;
    }
    END {
        if( sum )
            printf( "%s; %.3f\n", l, (f/sum) * 100 );
    }
' input-file
 cat input-file
     39 ,2012/01,0
     22 ,2012/02,0
      2 ,2012/02,1
     23 ,2012/03,0
      3 ,2012/03,1
     16 ,2012/04,0
      2 ,2012/04,1
      8 ,2012/05,0
      2 ,2012/05,1
      2 ,2012/06,0
      2 ,2012/07,1
 bash awk
2012/01; 0.000
2012/02; 91.667
2012/03; 88.462
2012/04; 88.889
2012/05; 80.000
2012/06; 100.000
2012/07; 100.000

First line should have "100" instead.
2nd line from the bottom - its ok, but last line - it should be "0" instead "100"

Any advice ?

Hi, you kept in && NR > 1 , that shouldn't be there..

--
So, records that are missing have a value of 0? Try:

awk -F, 'function pr(){printf "%s;%.2f\n",p,100*f/s} p!=$2{if(p)pr(); p=$2; f=$3==0?$1:0; s=0}{s+=$1} END{pr()}' infile
awk -F, '
  function pr(){
    printf "%s;%.2f\n",p,100*f/s
  } 
  p!=$2{
    if(p)pr()
    p=$2
    f=$3==0?$1:0
    s=0
  }
  {
    s+=$1
  } 
  END{
    pr()
  }
' infile

@Scrutinizer you are AMAZING. Your script is working perfectly !

Many thanks for support

Best regards,