列中出现整数 - 添加为新列
Occurence of an integer in a column - Add as a new column
我有一个包含 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[]++}; END { for(k in h) print k, h[k] }' input.tab
实际上显示第 7 列,但不显示其余列。我还发现这段代码:
awk '{print ,,,,,}'
打印所有列,所以我认为 "this should work":
awk '{print ,,,,,,};{h[]++}; END { for(k in h) print k, h[k] }' input.tab > output.tab
但显然没有。我能做到的最好的事情是在文件底部打印所有 6 个原始列和我需要的输出,但我需要它作为第 7 列。
我熟悉基本的 shell 命令,但不熟悉 AWK 语言。
我假设具有相同第 3 个字段的记录是连续的:
awk 'b!={for(j=0;j<i;j++){print a[j],i};delete a;b=;i=0;}{a[i++]=[=10=]}END{for (j=0;j<i;j++){print a[j],i}}' file
详情:
awk '
b!= { # 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=; # store the current "new" field
i=0;
}
{ a[i++]=[=11=] } # 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
不幸的是,您必须读取文件两次才能工作,这取决于大小,效率可能非常低。
无论哪种方式,你都接近了:
awk '{h[]++}; END { for(k in h) print k, h[k] }' input.tab
正在 h[]
中构建地图,以 </code> 的值为键并存储它出现的次数,然后在读取所有行后,打印出该地图。</p>
<p>你想要的是这样的:</p>
<pre><code>awk 'FNR==NR{h[]++;next} {=h[]; print}' input.tab input.tab
第一次读取文件时,我们将 </code> 的映射构建为它的计数,然后第二次读取(当 <code>FNR!=NR
时)我们将该值添加为 </code> , 然后打印结果行。</p>
<p>例如</p>
<pre><code>$awk 'FNR==NR{h[]++;next} {=h[]; 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"}
以将定界符和输出定界符设置为制表符,因为它默认为 space,如我上面的输出所示。
awk 'BEGIN{FS=OFS="\t"} FNR==NR{h[]++;next} {=h[]; print}' input.tab input.tab
我有一个包含 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[]++}; END { for(k in h) print k, h[k] }' input.tab
实际上显示第 7 列,但不显示其余列。我还发现这段代码:
awk '{print ,,,,,}'
打印所有列,所以我认为 "this should work":
awk '{print ,,,,,,};{h[]++}; END { for(k in h) print k, h[k] }' input.tab > output.tab
但显然没有。我能做到的最好的事情是在文件底部打印所有 6 个原始列和我需要的输出,但我需要它作为第 7 列。
我熟悉基本的 shell 命令,但不熟悉 AWK 语言。
我假设具有相同第 3 个字段的记录是连续的:
awk 'b!={for(j=0;j<i;j++){print a[j],i};delete a;b=;i=0;}{a[i++]=[=10=]}END{for (j=0;j<i;j++){print a[j],i}}' file
详情:
awk '
b!= { # 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=; # store the current "new" field
i=0;
}
{ a[i++]=[=11=] } # 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
不幸的是,您必须读取文件两次才能工作,这取决于大小,效率可能非常低。
无论哪种方式,你都接近了:
awk '{h[]++}; END { for(k in h) print k, h[k] }' input.tab
正在 h[]
中构建地图,以 </code> 的值为键并存储它出现的次数,然后在读取所有行后,打印出该地图。</p>
<p>你想要的是这样的:</p>
<pre><code>awk 'FNR==NR{h[]++;next} {=h[]; print}' input.tab input.tab
第一次读取文件时,我们将 </code> 的映射构建为它的计数,然后第二次读取(当 <code>FNR!=NR
时)我们将该值添加为 </code> , 然后打印结果行。</p>
<p>例如</p>
<pre><code>$awk 'FNR==NR{h[]++;next} {=h[]; 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"}
以将定界符和输出定界符设置为制表符,因为它默认为 space,如我上面的输出所示。
awk 'BEGIN{FS=OFS="\t"} FNR==NR{h[]++;next} {=h[]; print}' input.tab input.tab