整数在列中的出现 - 添加为新列



我有一个带有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

最新更新