我想用来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"
sed
awk
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}'
该解决方案将在问题文本中进行额外的必要澄清后进行更新。