AishwaryaKulkarni
AishwaryaKulkarni

Reputation: 784

Divide each row by max value in awk

I am trying to divide the rows by the max value in that row as (with rows having all columns as NA)

    r1  r2  r3  r4
a   0   2.3 1.2 0.1
b   0.1 4.5 9.1 3.1
c   9.1 8.4 0   5

I get

    r1  r2  r3  r4
a   0   1   0.52173913  0.043478261
b   0.010989011 0.494505495 1   0.340659341
c   1   0.923076923 0   0.549450549

I tried to calculate max of each row by executing

  awk '{m=$1;for(i=1;i<=NF;i++)if($i>m)m=$i;print m}' file.txt > max.txt

then pasted it as the last column to the file.txt as

paste file.txt max.txt > file1.txt

I am trying to execute a code where the last column will divide all the columns in that line , but first I needed to format each line hence I am stuck at

awk '{for(i=1;i<NF;i++) printf "%s " $i,$NF}' file1.txt

I am trying to print each combination for that line and then print the next lines combinations on new line. But I want to know if there is a better way to do this.

Upvotes: 1

Views: 512

Answers (2)

RavinderSingh13
RavinderSingh13

Reputation: 133770

Following awk may help you on same:

awk '
FNR==1{
  print;
  next
}
{
  len=""
  for(i=2;i<=NF;i++){
     len=len>$i?len:$i};
  printf("%s%s", $1, OFS)
}
{
  for(i=2;i<=NF;i++){
     printf("%s%s",$i>0?$i/len:0,i==NF?RS:FS)}
}
'    Input_file

Explanation: Adding explanation too here with solution now:

awk '
FNR==1{  ##FNR==1 is a condition where it will check if it is first line of Input_file then do following:
  print; ##printing the current line then.
  next   ##next is awk out of the box keyword which will skip all further statements now.
}
{
  len="" ##variable named len(which contains the greatest value in a line here)
  for(i=2;i<=NF;i++){ ##Starting a for loop here starting from 2nd field to till value of NF which means it will cover all the fields on a line.
     len=len>$i?len:$i}; ##Creating a variable named len here whose value is $1 if it is NULL and if it is greater than current $1 then it remains same else will be $1
  printf("%s%s", $1, OFS) ##Printing the 1st column value here along with space.
}
{
  for(i=2;i<=NF;i++){ ##Starting a for loop here whose value starts from 2 to till the value of NF it covers all the field of current line.
     printf("%s%s",$i>0?$i/len:0,i==NF?RS:FS)} ##Printing current field divided by value of len varible(which has maximum value of current line), it also checks a conditoin if value of i equals to NF then print new line else print space.
}
'  Input_file          ##mentioning the Input_file name here.

Upvotes: 1

karakfa
karakfa

Reputation: 67567

awk to the rescue!

$ awk 'NR>1 {m=$2; for(i=3;i<=NF;i++) if($3>m) m=$3; 
             for(i=2;i<=NF;i++) $i/=m}1' file

    r1  r2  r3  r4
a 0 1 0.521739 0.0434783
b 0.0222222 1 2.02222 0.688889
c 1 0.923077 0 0.549451

Upvotes: 3

Related Questions