查找两行之间的差异并将它们相加

查找两行之间的差异并将它们相加

我想用来awk将列添加在一起,但最多只能添加 1 个列,并且只能添加某些列。

这是我正在使用的输入文件的样子。

1   119 .   A   T   1000    PASS    MID=183;S=0;DOM=0.5;PO=1;GO=337;MT=1;AC=3;DP=1000;MULTIALLELIC  GT  0|0 1|0 0|0 0|0
1   119 .   A   T   1000    PASS    MID=362;S=0;DOM=0.5;PO=1;GO=562;MT=1;AC=2;DP=1000;MULTIALLELIC  GT  0|0 1|0 0|1 0|0

我想要它的样子

1   119 .   A   T   1000    PASS    MID=183;S=0;DOM=0.5;PO=1;GO=337;MT=1;AC=5;DP=1000   GT  0|0 1|0 0|1 0|0

所以我需要添加的唯一列是 AC=# 以及 0 和 1。我遇到的问题是处理其中包含文本的行和两个值均为 1 的行(我希望结果为 1)以及更改文件中间的分隔符。

到目前为止,awk 'NR%2 { split($0, a) ; next } { for (i=1; i<=NF; i++) printf " %d", a[i]+$i ; print "" } ' 不幸的是,这会将文本转换为 0,并且不会输出 ;、| 和制表符。

答案1

你的桌子很难处理,但实现此目的的一种方法是将工作分解为多个步骤。首先将数据保存在名为 的文件中data.txt,然后:

  • 将表格转换为固定宽度的列,并用 columns替换空格" "、等号=和冒号。您可以通过组合 和 中的函数来实现此目的,如下所示:";""\t"sedawk

sed 's/=/\t/g; s/;/\t/g' data.txt | awk '{printf "%-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s%-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s\n", $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33}'

输出:

1      119   .     A     T     1000  PASS  MID   183   S     0     DOM   0.5   PO    1     GO    337   MT    1    AC    3     DP    1000  MULTIALLELIC GT    0|0   1|0   0|0   0|0        
1      119   .     A     T     1000  PASS  MID   362   S     0     DOM   0.5   PO    1     GO    562   MT    1    AC    2     DP    1000  MULTIALLELIC GT    0|0   1|0   0|1   0|0  
  • 对特定列中的值求和,在您的情况下为 column number #21。您可以通过将上一步的输出传输到以下命令来完成此操作:

awk '{ sum21+=$21} END {print sum21}')

输出:

5

- 使用以下命令从表中提取第一行:

sed 's/=/\t/g; s/;/\t/g' data.txt| awk '{printf "%-5s  %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s%-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s\n", $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33}' | head -1

输出:

1      119   .     A     T     1000  PASS  MID   183   S     0     DOM   0.5   PO    1     GO    337   MT    1    AC    3     DP    1000  MULTIALLELIC GT    0|0   1|0   0|0   0|0        

field #21- 将上一步中的值替换为原始表中sum-value第 21 列的值reconstruct the spaces, colons and the other symbols,如下所示:

awk '{print $1,$2,$3,$4,$5,$6,$7,$8"="$9";"$10"="$11";"$12"="$13";"$14"="$15";"$16"="$17";"$18"="$19";"$20,"=",$21='$sum'";"$22"="$23";"$24,$25,$26,$27,$28,$29,$30,$31,$32,$33}'

输出:

1 119 . A T 1000 PASS MID=183;S=0;DOM=0.5;PO=1;GO=337;MT=1;AC = 5;DP=1000;MULTIALLELIC GT 0|0 1|0 0|0 0|0    

在 bash 中,您可以按如下方式执行此操作:

#!/bin/bash
sum_col21=$(sed 's/=/\t/g; s/;/\t/g' data.txt| awk '{printf "%-5s  %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s%-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s\n", $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33}' | awk '{ sum21+=$21} END {print sum21}')

first_row=$(sed 's/=/\t/g; s/;/\t/g' data.txt| awk '{printf "%-5s  %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s%-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s\n", $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33}' | head -1)


echo $first_row | awk '{print $1,$2,$3,$4,$5,$6,$7,$8"="$9";"$10"="$11";"$12"="$13";"$14"="$15";"$16"="$17";"$18"="$19";"$20,"=",$21='$sum_col21'";"$22"="$23";"$24,$25,$26,$27,$28,$29,$30,$31,$32,$33}'

该解决方案将在问题文本中进行额外的必要澄清后进行更新。

相关内容