我有一个包含6列的表格文件。我需要做的是添加第7列,用于计算第3列中值的出现次数。我使用Excel进行计算,添加公式
=countif(C:C,$C1)
但文件很大,我有很多
例如:
我的意见是:
0 SL3.0ch03 7675648 21M GATCACTCCAAACTCATCATA NM:i:2
0 SL3.0ch03 7675648 21M GATCACTCCAAACTCATCATA NM:i:2
0 SL3.0ch03 7675648 21M GATCACTCCAAACTCATCATA NM:i:2
0 SL3.0ch03 7675649 21M ATCACTCCAAACTCATCATAC NM:i:1
0 SL3.0ch03 7675649 21M ATCACTCCAAACTCATCATAC NM:i:1
0 SL3.0ch03 7675649 21M CTCACTCCAAACTCATCATAC NM:i:2
0 SL3.0ch03 7675649 21M ATCACTCCAAACTCATCATAC NM:i:1
0 SL3.0ch03 7675649 21M ATCACTCCAAACTCATCATAC NM:i:1
0 SL3.0ch03 7675650 21M TCACTCCAAACTCATCATACT NM:i:1
0 SL3.0ch03 7675650 21M TCACTCCAAACTCATCATACT NM:i:1
0 SL3.0ch03 7675650 21M TCACTCCAAACTCATCATACT NM:i:1
0 SL3.0ch03 7675650 21M TCACTCCAAACTCATCATACT NM:i:1
我需要像这样的输出:
0 SL3.0ch03 7675648 21M GATCACTCCAAACTCATCATA NM:i:2 3
0 SL3.0ch03 7675648 21M GATCACTCCAAACTCATCATA NM:i:2 3
0 SL3.0ch03 7675648 21M GATCACTCCAAACTCATCATA NM:i:2 3
0 SL3.0ch03 7675649 21M ATCACTCCAAACTCATCATAC NM:i:1 5
0 SL3.0ch03 7675649 21M ATCACTCCAAACTCATCATAC NM:i:1 5
0 SL3.0ch03 7675649 21M CTCACTCCAAACTCATCATAC NM:i:2 5
0 SL3.0ch03 7675649 21M ATCACTCCAAACTCATCATAC NM:i:1 5
0 SL3.0ch03 7675649 21M ATCACTCCAAACTCATCATAC NM:i:1 5
0 SL3.0ch03 7675650 21M TCACTCCAAACTCATCATACT NM:i:1 4
0 SL3.0ch03 7675650 21M TCACTCCAAACTCATCATACT NM:i:1 4
0 SL3.0ch03 7675650 21M TCACTCCAAACTCATCATACT NM:i:1 4
0 SL3.0ch03 7675650 21M TCACTCCAAACTCATCATACT NM:i:1 4
我尝试了一些我发现的东西:
awk '{h[$3]++}; END { for(k in h) print k, h[k] }' input.tab
实际显示第7列,但不显示其余列。我还发现这段代码:
awk '{print $1,$2,$3,$4,$5,$6}'
打印所有列,所以我认为“这应该有用”:
awk '{print $1,$2,$3,$4,$5,$6,$7};{h[$3]++}; END { for(k in h) print k, h[k] }' input.tab > output.tab
但显然没有。我能做到的最好的事情是打印所有6个原始列和我需要的文件底部输出,但我需要它作为第7列。
我熟悉基本的shell命令,但不熟悉AWK语言。
答案 0 :(得分:1)
不幸的是,为了实现这个目的,您必须阅读两次文件,这取决于尺寸,效率可能非常低。
无论哪种方式,你都很亲密:
awk '{h[$3]++}; END { for(k in h) print k, h[k] }' input.tab
正在h[]
中构建一个以$3
的值为基础的地图,并存储其出现次数,然后在读取所有行后,打印出该地图。
你想要的是这样的:
awk 'FNR==NR{h[$3]++;next} {$7=h[$3]; print}' input.tab input.tab
首先阅读文件,我们将$3
的地图构建为与您相同的计数,然后第二次读取(当FNR!=NR
时)我们将该值添加为{{1然后打印出结果行。
e.g。
$7
另外,如果这些是真正以制表符分隔的,那么您将要添加$awk 'FNR==NR{h[$3]++;next} {$7=h[$3]; print}' input.tab input.tab
0 SL3.0ch03 7675648 21M GATCACTCCAAACTCATCATA NM:i:2 3
0 SL3.0ch03 7675648 21M GATCACTCCAAACTCATCATA NM:i:2 3
0 SL3.0ch03 7675648 21M GATCACTCCAAACTCATCATA NM:i:2 3
0 SL3.0ch03 7675649 21M ATCACTCCAAACTCATCATAC NM:i:1 5
0 SL3.0ch03 7675649 21M ATCACTCCAAACTCATCATAC NM:i:1 5
0 SL3.0ch03 7675649 21M CTCACTCCAAACTCATCATAC NM:i:2 5
0 SL3.0ch03 7675649 21M ATCACTCCAAACTCATCATAC NM:i:1 5
0 SL3.0ch03 7675649 21M ATCACTCCAAACTCATCATAC NM:i:1 5
0 SL3.0ch03 7675650 21M TCACTCCAAACTCATCATACT NM:i:1 4
0 SL3.0ch03 7675650 21M TCACTCCAAACTCATCATACT NM:i:1 4
0 SL3.0ch03 7675650 21M TCACTCCAAACTCATCATACT NM:i:1 4
0 SL3.0ch03 7675650 21M TCACTCCAAACTCATCATACT NM:i:1 4
以将分隔符和输出分隔符设置为制表符,因为它默认为空格,如上面的输出所示。
BEGIN{FS=OFS="\t"}
答案 1 :(得分:0)
我假设具有相同第3个字段的记录是连续的:
awk 'b!=$3{for(j=0;j<i;j++){print a[j],i};delete a;b=$3;i=0;}{a[i++]=$0}END{for (j=0;j<i;j++){print a[j],i}}' file
细节:
awk '
b!=$3 { # when the stored 3rd field is different from the current
for(j=0;j<i;j++){ print a[j],i }; # display stored records
delete a; # delete the array
b=$3; # store the current "new" field
i=0;
}
{ a[i++]=$0 } # store the current record and increment the index
# display the last stored records
END {for (j=0;j<i;j++){print a[j],i}}
' file