Conditional Arithmetic in [g]awk

I am having a difficult time getting an awk one-liner to work correctly that runs a mathematical operation upon values in a field when matching a given criteria.

I would like to subtract 1 from every value in field $6 that is greater than 12. In this particular case it is only a constant of value 1, and I suppose this can be accomplished with a decrement, but I would like to learn how to do this with any numerical constant. If possible, I would also very much appreciate being pointed in the right direction should I want a similar conditional operation to be run concurrently on multiple fields. That is to say, if I would like to subtract 1 from every value in $6 greater than 12 and (&&) say, add 2 to every value in $1 that is less than 11. In other words, would it be possible to indicate how I may have the skeletal syntax for additional conditional operations? Thus, my data looks like this:

    7 100   1   1   7   6 509  1 509  1 501  2 501  2 505  3 505  3  -1 -1  -1 -1
    8 100   1   1   8   7 509  1 509  1 501  2 501  2 504  3 504  3  -1 -1  -1 -1
    9 100   2   2   9   8 501  1 501  1 503  2 503  2  -1 -1  -1 -1
   10 100   2   2  10   9 501  2 509  0 502  0 501  1 504  3 504  3  -1 -1  -1 -1
   11 100   2   2  11  10 501  3 509  0 502  0 509  0 503  4 501  1 504  5 503  3  -1 -1 505  4  -1 -1  -1 -1
   12 100   3   3  12  11 510  1 510  1 501  2 501  2 503  3 503  3 505  4 505  4  -1 -1  -1 -1
   13 100   3   3  13  12 521  2 519  0 503  3 521  1 504  4 503  2  -1 -1 505  3  -1 -1  -1 -1
   14 100   3   3  14  13 509  1 509  1 502  2 502  2 521  3 521  3  -1 -1  -1 -1
   15 100   4   4  15  14 501  1 501  1 504  3 503  0 505  0 504  2  -1 -1  -1 -1
   16 100   4   4  16  -1 505  0  -1 -1 501  0  -1 -1 504  0  -1 -1  -1 -1  -1 -1
   17 100   4   4  17  -1 501  0  -1 -1 503  0  -1 -1 504  0  -1 -1  -1 -1  -1 -1
   18 100   4   4  -1  15  -1 -1 509  0  -1 -1 504  0  -1 -1  -1 -1

My desired output is (NB: the change in font color is only to emphasize the desired operation relative to input):

    7 100   1   1   7   6 509  1 509  1 501  2 501  2 505  3 505  3  -1 -1  -1 -1
    8 100   1   1   8   7 509  1 509  1 501  2 501  2 504  3 504  3  -1 -1  -1 -1
    9 100   2   2   9   8 501  1 501  1 503  2 503  2  -1 -1  -1 -1
   10 100   2   2  10   9 501  2 509  0 502  0 501  1 504  3 504  3  -1 -1  -1 -1
   11 100   2   2  11  10 501  3 509  0 502  0 509  0 503  4 501  1 504  5 503  3  -1 -1 505  4  -1 -1  -1 -1
   12 100   3   3  12  11 510  1 510  1 501  2 501  2 503  3 503  3 505  4 505  4  -1 -1  -1 -1
   13 100   3   3  13  12 521  2 519  0 503  3 521  1 504  4 503  2  -1 -1 505  3  -1 -1  -1 -1
   14 100   3   3  14  12 509  1 509  1 502  2 502  2 521  3 521  3  -1 -1  -1 -1
   15 100   4   4  15  13 501  1 501  1 504  3 503  0 505  0 504  2  -1 -1  -1 -1
   16 100   4   4  16  -1 505  0  -1 -1 501  0  -1 -1 504  0  -1 -1  -1 -1  -1 -1
   17 100   4   4  17  -1 501  0  -1 -1 503  0  -1 -1 504  0  -1 -1  -1 -1  -1 -1
   18 100   4   4  -1  14  -1 -1 509  0  -1 -1 504  0  -1 -1  -1 -1

I have attempted:

awk '{if($6>12); $6-=1; print}' File
awk '{if($6>12){$6=-1; print}}' File
awk '{x=$6; if(x>12); x=-1}{print}' File
$ awk '{if ($6 > 12) { $6--}; if ($1 < 11) {$1+=2} print } ' File
1 Like

Try also

awk '{$6 -= ($6>12); $1 += ($1<11)?2:0; print } ' OFS="\t" file

EDIT: or even (given that $1 won't assume -2)

awk '($6 -= ($6>12)) && ($1 += ($1<11)?2:0)' OFS="\t" file
1 Like

These can also be written as:

awk '{$6 -= ($6>12); $1 += 2*($1<11); print } ' OFS="\t" file
awk '($6 -= ($6>12)) && $1 += 2*($1<11)' OFS="\t" file

under the same conditions.

1 Like