用于比较,选择和处理列的awk

时间:2015-10-01 13:50:13

标签: linux bash awk

我有一个列表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    -

我希望使用一些规则从第3列($ 3)和第8列($ 8)中提取数据:

比较第4列($ 4)和第9列($ 9)

i)如果两者都是否定的,则输出" -1"。

ii)如果$ 4< 0和$ 9> 0,输出$ 3;如果$ 4> 0和$ 9< 0,输出$ 8.

iii)如果$ 4和$ 9> 0,则输出$ 3 + $ 8

所以我尝试过这样的事情:

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

不知何故,这个脚本没有给出正确的行数(应该等于list.txt)或正确的数据:(

使用list.txt应该

0.25
0.13
0.56
-1
0.12
1.01

2 个答案:

答案 0 :(得分:2)

通过使用嵌套的for循环,您将第4列的所有值与第9列的所有值进行比较,而不是比较相应行的值。

在读取每行时,可能更符合您的要求:

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";
    } 
}'

答案 1 :(得分:-1)

虽然有一个公认的答案我不认为这是惯用的awk。你绝对可以摆脱if / else块而且应该。

$ 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

更好

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