Home > other >  Awk access variable more than once
Awk access variable more than once

Time:07-12

I am trying to access a variable defined in awk multiple times, but it does not seem to work.

Lets assume we have a data.txt with contents:

1 2
2 3
3 4

If we do awk with:

cat data.txt | awk 'sum=($1 $2), div1=(sum/$1) {print " sum: " sum " div1: " div1 " data: " $0}'

It works fine and we get an output of

sum: 3 div1: 3 data: 1 2
sum: 5 div1: 2.5 data: 2 3
sum: 7 div1: 2.33333 data: 3 4

If I try to access the sum multiple times, I get an error

cat data.txt | awk 'sum=($1 $2), div1=(sum/$1), div2=(sum/$2) {print " sum: " sum " div1: " div1 " div2: " div2 " data: " $0}'

Even if I change div2=(sum/$2) to div1=(sum/$1), which is exactly the same as before, I will still get the error:

awk: line 1: syntax error at or near ,

How can I get around this issue and access any specific variable assigned in awk to be accessible multiple times?

CodePudding user response:

The part before the {} block is supposed to be a condition. Put variable assignments inside the {}. Multiple statements are separated using ;.

cat data.txt | awk '{sum=($1 $2); div1=(sum/$1); div2=(sum/$2); print " sum: " sum " div1: " div1 " div2: " div2 " data: " $0}'

CodePudding user response:

Removing comma separated assignments and cleaning it further:

awk '{sum=$1 $2; print "sum:", sum, "div1:", sum/$1, "div2:", sum/$2, "data:", $0}' data.txt

sum: 3 div1: 3 div2: 1.5 data: 1 2
sum: 5 div1: 2.5 div2: 1.66667 data: 2 3
sum: 7 div1: 2.33333 div2: 1.75 data: 3 4

For more control over floating point formatting and spacing etc use printf or OFMT like this:

awk -v OFMT='%.2g' '{sum=$1 $2; print "sum:", sum, "div1:", sum/$1, "div2:", sum/$2, "data:", $0}' data.txt

sum: 3 div1: 3 div2: 1.5 data: 1 2
sum: 5 div1: 2.5 div2: 1.7 data: 2 3
sum: 7 div1: 2.3 div2: 1.8 data: 3 4

CodePudding user response:

technically, you can do it entire in the pattern space too, just less elegant :

mawk '($4=($3=___=(_=$1) (__=$ 2))\
                  /_/(1   4^-5^2)) \
          ($5=___/__/(1   4^-5^2))_' CONVFMT='%.10f' OFS='\t'
1    2    3    3.0000000000    1.5000000000
2    3    5    2.5000000000    1.6666666667
3    4    7    2.3333333333    1.7500000000

The extra bit of 2^-50 is to force floating point output, -- but since it's also far beyond the output precision level, the chance of it affecting the output is miniscule -- TL;DR adding something near precision epsilon

  • Related