对字符串计数进行数学运算(并使用awk进行文本解析)

时间:2017-05-22 23:04:55

标签: parsing awk

我有一个带有标题的4列文件(input.file):

something1 something2 A B

后跟许多具有相同格式的4列行(例如):

ID_00001 1 0 0
ID_00002 0 1 0
ID_00003 1 0 0
ID_00004 0 0 1
ID_00005 0 1 0
ID_00006 0 1 0
ID_00007 0 0 0
ID_00008 1 0 0

其中" 1 0 0"代表" AA"," 0 1 0"意味着" AB"和" 0 0 1"意味着" BB"

首先,我想创建第5列来识别这些表示:

ID_00001 1 0 0 AA
ID_00002 0 1 0 AB
ID_00003 1 0 0 AA
ID_00004 0 0 1 BB
ID_00005 0 1 0 AB
ID_00006 0 1 0 AB
ID_00007 0 0 0 no data
ID_00008 1 0 0 AA

请注意,A和B和B需要从标题行的第3列和第4列进行解析,因为它们并不总是A和B.

接下来,我想做数学"关于(新)第5栏的计数如下:

(2BB + AB) / 2(AA + AB + BB)

使用该示例,数学将给出:

(2(1)+ 3)/ 2(3 + 3 + 1)= 5/14 = 0.357

我想附加到所需输出文件(output.file)的末尾:

ID_00001 1 0 0 AA
ID_00002 0 1 0 AB
ID_00003 1 0 0 AA
ID_00004 0 0 1 BB
ID_00005 0 1 0 AB
ID_00006 0 1 0 AB
ID_00007 0 0 0 no data
ID_00008 1 0 0 AA

B_freq = 0.357

到目前为止,我有这个:

awk '{ if ($2 = 1) {print $0, $5="AA"} \
else if($3 = 1) {print $0, $5="AB"} \
else if($4 = 1) {print $0, $5="BB"} \
else {print$0, $5="no data"}}' input.file > output.file

显然,我无法弄清楚如何解析第1行的信息(标题行,编辑出来"第1列和第34列;),更不用说算数了。

谢谢你们!

1 个答案:

答案 0 :(得分:1)

更有条理的方法......

NR==1 {a["100"]=$3$3; a["010"]=$3$4; a["001"]=$4$4; print; next}   
      {k=$2$3$4; 
       print $0, (k in a)?a[k]:"no data";
       c[k]++}
END   {printf "\nB freq = %.3f\n",
       (2*c["001"]+c["010"]) / 2 / (c["100"]+c["010"]+c["001"])}

<强>更新 对于非二进制数据,您可以通过一些预处理遵循相同的逻辑。这样的东西应该在主块中起作用:

for(i=2;i<5;i++) v[i]=(($i-0.9)^2<=0.1^2)?1:0;
k=v[2] v[3] v[4];
...

这里的值在一个范围内被量化为[0.8,1],否则为零。

在第一个区块中捕获“B”或替换集合h=$4并将其用作printf "\n%s freq...",h,(2*c...