【问题标题】:Do math on string count (and text parsing with awk)对字符串计数进行数学运算(以及使用 awk 进行文本解析)
【发布时间】:2017-10-22 17:33:40
【问题描述】:

我有一个带有标题的 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

请注意,需要从标题行的第 3 列和第 4 列解析 A 和 B,因为它们并不总是 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 列”)中的信息,更不用说数学了。

谢谢大家!

【问题讨论】:

  • ...how to parse the info from column 1...??
  • 表示第 1 行(标题行),对此感到抱歉
  • 更具体地说,我无法(例如)解析标题行第 3 列中的“A”并将其(两次)放在后续“1 0 0”行的第 5 列中。
  • 现在我明白了,看看我更新的答案。

标签: parsing awk


【解决方案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...

【讨论】:

  • 您的回答非常适合被问到的问题。如何更改代码以允许输入文件主体中每列 2、3 和 4 的值范围(具体来说,如果我想接受范围 >= 0.8 &&
  • 我在原始脚本中的“END {”和“printf”之间放置了附加(预处理)脚本。与原始脚本相比,我生成了一个有效但未更改的输出。我不确定我是否将附加脚本放在了错误的位置,或者它是否不起作用。谢谢。
  • 它应该在主块中,在k= 行之前(并使用'k`的新定义)
  • 成功了!!现在花一些时间弄清楚你做了什么!非常感谢您的帮助。
  • 如何将标题行第4列的实际值(不同输入文件中不同的字符串)合并到输出文件的最后一行,而不是使用“\nB freq”?谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多