我有一个像这样的文本文件:
示例:
chr12 58146000 58146050 79 chr12 58145961 58146075 CDK4
chr12 58146050 58146075 81 chr12 58145961 58146075 CDK4
chr12 69082750 69082800 57 chr12 69082741 69082833 NUP107
chr12 99038450 99038479 81 chr12 99038300 99038479 IKBIP
chr12 104680862 104680887 512 chr12 104680862 104680887 TXNRD1
chr12 104682708 104682750 134 chr12 104682708 104682818 TXNRD1
我想根据第8列对它们进行分组,并对属于同一组的第4列的值求和,结果将是一个由制表符分隔的文件,其中包含2列。第一列是求和后的数字(从第四列开始),第二列是组名(从第八列开始)。我尝试了以下代码,但未返回我想要的。你知道如何解决吗?
cut -d'\t' -f 8 | sort | uniq -c | awk '{ print sum($4), $8 }' infile > outfile
这是预期的输出:
预期输出:
160 CDK4
57 NUP107
81 IKBIP
646 TXNRD1
答案 0 :(得分:4)
$ awk -v OFS='\t' '{sum[$8]+=$4} END{for (grp in sum) print sum[grp], grp}' file
81 IKBIP
57 NUP107
646 TXNRD1
160 CDK4
答案 1 :(得分:0)
另一种方法,使用GNU datamash代替awk:
$ datamash -s groupby 8 sum 4 < data.tsv | datamash reverse
160 CDK4
81 IKBIP
57 NUP107
646 TXNRD1
这假设输入文件中的列也是制表符分隔的。如果不是,请将-W
添加到选项中。
答案 2 :(得分:0)
使用perl
perl -lane ' $kv{$F[7]}+=$F[3]; END { for(keys %kv) { print "$_\t$kv{$_}" }} '
使用给定的输入
$ cat elly.txt
chr12 58146000 58146050 79 chr12 58145961 58146075 CDK4
chr12 58146050 58146075 81 chr12 58145961 58146075 CDK4
chr12 69082750 69082800 57 chr12 69082741 69082833 NUP107
chr12 99038450 99038479 81 chr12 99038300 99038479 IKBIP
chr12 104680862 104680887 512 chr12 104680862 104680887 TXNRD1
chr12 104682708 104682750 134 chr12 104682708 104682818 TXNRD1
$ perl -lane ' $kv{$F[7]}+=$F[3]; END { for(keys %kv) { print "$_\t$kv{$_}" }} ' elly.txt
NUP107 57
TXNRD1 646
IKBIP 81
CDK4 160
$