我一直在努力寻找解决方案,但现在我需要一些帮助。
首先,作为输入,我有一个具有以下结构的大文件(5.5G):
scaffold4691_size302 2 T 1
scaffold4691_size302 3 A 1
scaffold4691_size302 4 a 1
scaffold4691_size302 5 a 1
scaffold4691_size302 6 g 2
scaffold4691_size302 7 c 2
scaffold4691_size302 8 c 2
scaffold4692_size187 68 g 4
scaffold4692_size187 69 c 4
scaffold4692_size187 70 a 4
scaffold4692_size187 71 a 4
我想要的是计算第一列($1)的每个ID,第四列($4)中的值大于或等于X(例如玩具模型中的X=4)的次数。
因此,作为输入,我期望:
scaffold4691_size302 0
scaffold4691_size187 4
我可以很容易地在 python 上完成它,因为我对它更舒服,但尺寸太大了。
到目前为止,我这样做了:
awk 'NR>1 { scf=$1; { if ($4>=4){count++;}}} {print scf "\t" count}' toyModel
但它返回了我所有的行和总数。我想知道如何刷新新 ID 的计数。
答案1
您需要累积每个 id 的计数并在处理文件后打印结果:
awk '!counts[$1] { counts[$1] = 0 }; $4 >= 4 { counts[$1]++ }; END { for (key in counts) print key, counts[key] }' toyModel
第一条语句确保我们测量的 id 永远不会匹配标准(最终输出为 0)。第二个增加匹配行的计数。最后一条语句迭代键 (ids) 并打印出键和匹配计数。
如果此方法的大小太大(数组counts
变得太大),并且您的 id 在文件中是连续的,则可以改用此方法:
awk 'curid != $1 { if (NR > 1) print curid, count; curid = $1; count = 0 }; $4 >= 4 { count++ }; END { print curid, count }' toyModel
这会保留当前的 id 和计数,并在 id 更改时(以及最后)打印它们。每当第四个字段大于 4 时,计数就会递增,每当 id 更改时,计数就会重置。
答案2
perl -lane '$h{$F[0]} += $F[3] >= 4 ? 1 : 0}{print "$_\t$h{$_}" for keys %h' toyModel