在awk中对文本文件进行分组和汇总

在awk中对文本文件进行分组和汇总,awk,Awk,我有一个类似以下示例的文本文件: 例如: 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

我有一个类似以下示例的文本文件:

例如:

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列的值相加,结果将是一个由两列组成的制表符分隔的文件。第一列是求和后生成的数字(从第四列开始),第二列是组名(从第八列开始)。我尝试了以下代码,但它没有返回我想要的。你知道怎么修吗

cut -d'\t' -f 8 | sort | uniq -c | awk '{ print sum($4), $8 }' infile > outfile
以下是预期输出:

160 CDK4
57  NUP107
81  IKBIP
646 TXNRD1
预期产出:

160 CDK4
57  NUP107
81  IKBIP
646 TXNRD1
使用替代awk的另一种方法:

$ datamash -s groupby 8 sum 4 < data.tsv | datamash reverse
160 CDK4
81  IKBIP
57  NUP107
646 TXNRD1
$datamash-s groupby 8和4

这假定输入文件中的列也是以制表符分隔的。如果不是,请在选项中添加
-W

使用
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

$

nit:问题指定“制表符分隔文件”作为输出,所以我建议
awk。。。OFS=\\t
而不是管道连接到
列-t
最终添加
| sort-k2
,使其与问题中要求的顺序相同,或者可能是
asorti
?在GNU上下文中。@Allan对输出进行排序不会产生问题中所示的顺序。如果OP需要一个特定的输出顺序,那么它可能与输入的顺序相同,而不是对输出进行排序,这在awk脚本中是很容易做到的,如果需要的话。