我有一个带有6列的表格文件。我需要做的是添加一个第七列,该列计算出3列中值的出现。
=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
实际显示第七列,但没有显示其余的列。我还发现此代码:
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列和在文件底部需要的输出,但我需要它作为第七列。
我熟悉基本的shell命令,但不熟悉尴尬语言。
不幸的是,您必须两次读取文件才能正常工作,这取决于大小,这可能是非常低效的。
无论哪种方式,您都很近: 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
时(,我们将该值添加为$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"}
以将定界符和输出定界符设置为选项卡,因为它默认为空格,如我上面的输出所示。
awk 'BEGIN{FS=OFS="t"} FNR==NR{h[$3]++;next} {$7=h[$3]; print}' input.tab input.tab
我假设具有相同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