我对awk
比较新,所以我有一个关于分割的简单问题,并在新专栏中打印结果。例如:
head data
1 13273 . G C 563 5 . 25 128
1 202259 . G T 675 8 . 12 130
1 598934 . C C 756 9 . 17 231
1 634112 . T C 125 1 . 32 89
1 779762 . G A 675 5 . 28 187
我想将第9列除以第10列,并将结果打印在新列11中,最好将新结果从高到低排序。例如:
1 634112 . T C 125 1 . 32 89 0.360
1 13273 . G C 563 5 . 25 128 0.195
1 779762 . G A 675 5 . 28 187 0.150
1 202259 . G T 675 8 . 12 130 0.092
1 598934 . C C 756 9 . 17 231 0.074
我只知道如何在R中执行此操作,但我想了解如何在awk
中执行此操作。谢谢!
答案 0 :(得分:2)
Awk对于第一个要求非常有表现力。如果你想要一个第11列,你可以发明它并将它设置为等于第9列除以第10列的结果。
可以在awk中进行排序,但是只需管道排序就会有点麻烦。 column命令使它更漂亮,仅此而已。
$ awk '{$11 = $9 / $10}1' file | sort -nr -k 11 | column -t
1 634112 . T C 125 1 . 32 89 0.359551
1 13273 . G C 563 5 . 25 128 0.195312
1 779762 . G A 675 5 . 28 187 0.149733
1 202259 . G T 675 8 . 12 130 0.0923077
1 598934 . C C 756 9 . 17 231 0.0735931
如果输出需要以制表符分隔,则可以设置OFS
变量(并忘记列命令):
$ awk -v OFS='\t' '{$11 = $9 / $10}1' file | sort -nr -k 11
1 634112 . T C 125 1 . 32 89 0.359551
1 13273 . G C 563 5 . 25 128 0.195312
1 779762 . G A 675 5 . 28 187 0.149733
1 202259 . G T 675 8 . 12 130 0.0923077
1 598934 . C C 756 9 . 17 231 0.0735931
最后,您可以使用sprintf
格式化示例输出中的最后一列:
$ awk -v OFS='\t' '{$11 = sprintf("%.3f", $9 / $10)}1' file | sort -nr -k 11
1 634112 . T C 125 1 . 32 89 0.360
1 13273 . G C 563 5 . 25 128 0.195
1 779762 . G A 675 5 . 28 187 0.150
1 202259 . G T 675 8 . 12 130 0.092
1 598934 . C C 756 9 . 17 231 0.074
<强>更新强>:
正如Ed Morton在他的回答中所示,三元运算符?:
可用于防止被零除。我在这里放了&#34; UND&#34;在第11栏中指出&#34; undefined&#34;,但当然你可以把它留空或放一些不同的价值。
$ awk -v OFS='\t' '{$11 = ($10 != 0) ? sprintf("%.3f", $9 / $10) : "UND"}1' file | sort -nr -k 11
1 634112 . T C 125 1 . 32 89 0.360
1 13273 . G C 563 5 . 25 128 0.195
1 779762 . G A 675 5 . 28 187 0.150
1 202259 . G T 675 8 . 12 130 0.092
1 598934 . C C 756 9 . 17 0 UND
在某些时候,您可能会认为awk程序变得足够复杂,以至于它在自己的文件中更好,重点在于可读性而不是紧凑性。
$ cat div.awk file
BEGIN { OFS="\t"}
{
if ($10 != 0) {
quotient = $9 / $10
$11 = sprintf("%.3f", quotient)
}
else {
$11 = "UND"
}
print
}
$ awk -f div.awk file | sort -nr -k 11
1 634112 . T C 125 1 . 32 89 0.360
1 13273 . G C 563 5 . 25 128 0.195
1 779762 . G A 675 5 . 28 187 0.150
1 202259 . G T 675 8 . 12 130 0.092
1 598934 . C C 756 9 . 17 0 UND
答案 1 :(得分:2)
使用GNU awk for sorted_in:
belongs_to
如果$ 10可以为零,则将$ cat tst.awk
{ a[NR]=$0; v[NR]=$9/$10 }
END {
PROCINFO["sorted_in"]="@val_num_desc"
for (i in v) {
print a[i] "\t" v[i]
}
}
$ awk -f tst.awk file
1 634112 . T C 125 1 . 32 89 0.359551
1 13273 . G C 563 5 . 25 128 0.195312
1 779762 . G A 675 5 . 28 187 0.149733
1 202259 . G T 675 8 . 12 130 0.0923077
1 598934 . C C 756 9 . 17 231 0.0735931
更改为v[NR]=$9/$10
或类似内容以防止被零除。