Parsing 对字符串计数进行数学计算(以及使用awk进行文本解析)

Parsing 对字符串计数进行数学计算(以及使用awk进行文本解析),parsing,awk,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 首先,我想创建一个第五列来识别这些表示: ID_000

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

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

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
请注意,需要从标题行的第3列和第4列解析A和B,因为它们并不总是A和B

接下来,我想对新列5的计数进行如下计算:

(2BB + AB) / 2(AA + AB + BB)
使用该示例,数学将给出:

21+3/23+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列)中的信息,更不用说数学了


谢谢大家

更结构化的方法

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]范围内被量化为1,否则为0


要在第一个块中捕获B或替换集h=$4并将其用作printf\n%s freq…,h,2*c…

…如何解析第1列中的信息…?意味着第1行是标题行,很抱歉,更具体地说,我无法解析标题行第3列中的A,并将其放在后续10行的第5列中两次。现在我明白了,请看我的最新答案。您的答案完全适用于所提出的问题。如果我想接受范围>=0.8&&我将附加的预处理脚本放在两个端点之间,那么如何更改代码以允许输入文件主体中第2、3和4列中的每一列的值的范围{和原始脚本中的printf。与原始脚本相比,我生成了一个有效但未更改的输出。我不确定是否将附加脚本放在了错误的位置,或者它是否不工作。谢谢。它应该位于主块中,在k=行之前,并使用“k”的新定义。它工作了!!现在花一些时间来弄清楚到底是什么完成了!非常感谢您的帮助。如何将标题行第4列的实际值(不同输入文件中的不同字符串)合并到输出文件的最后一行中,而不是使用\nB freq?谢谢