Turtle
Turtle

Reputation: 163

awk for comparing, selecting and processing columns

I have a list list.txt

1    10691    0.12    54    +    1    10692    0.13    55    -
2    10720    0.23    -1    +    2    10721    0.13    43    -
3    10832    0.43    123    +    3    10833    0.13    88    -
4    11032    0.22    -1    +    4    11033    0.13    -1    -
5    11248    0.12    45    +    5    11249    0.13    -1    -
6    15214    0.88    33    +    6    15215    0.13    45    -

I wish to extract data from columns 3 ($3) and 8 ($8) using a few rules:

Compare columns 4 ($4) and 9 ($9)

i) If both are negative, output "-1".

ii) If $4 < 0 and $9 > 0, output $3; If $4 > 0 and $9 < 0, output $8.

iii) If both $4 and $ 9 >0, output $3+$8

So I tried something like this:

awk '{a[$4]; b[$9]}
  END{
    for (x in a) {
      for (y in b) {
        if (x >0 && y >0) {
          print $3+$8
        }
        else if (x >0 && y <=0) {
          print $3;
        }
        else if (x <= 0 && y >0) {
          print $8;
        }
        else if (x <=0 && y <=0) {
          print "-1";
        } 
      }
    }
  }' list.txt

Somehow this script doesn't give the correct number of lines (should be equal to list.txt) or the right data :(

Using list.txt one should get

0.25
0.13
0.56
-1
0.12
1.01

Upvotes: 3

Views: 81

Answers (2)

karakfa
karakfa

Reputation: 67467

although there is an accepted answer I don't think it's idiomatic awk. You definitely can get rid of if/else blocks and should.

$ awk '{x=$4>0;y=$9>0} x&&y{w=$3+$8} x&&!y{w=$3} !x&&y{w=$8} !x&&!y{w=-1} {print w}' xy
0.25
0.13
0.56
-1
0.12
1.01

better yet

$ awk '{x=$4>0;y=$9>0} x{w=$3} y{w+=$8} !x&&!y{w=-1} {print w}' xy

Upvotes: -1

Vaughn Cato
Vaughn Cato

Reputation: 64308

By using the nested for loops, you are comparing all the values of column 4 with all the values of column 9 instead of comparing the values on corresponding rows.

Working with each line as it is read is probably more what you want:

awk '{  
    x=$4; y=$9;
    if (x >0 && y >0) {
      print $3+$8
    }
    else if (x >0 && y <=0) {
      print $3;
    }
    else if (x <= 0 && y >0) {
      print $8;
    }
    else if (x <=0 && y <=0) {
      print "-1";
    } 
}'

Upvotes: 2

Related Questions