我有一个制表符分隔文件,如下所示:
cluster.1 Adult.1
cluster.2 Comp.1
cluster.3 Adult.2
cluster.3 Pre.3
cluster.4 Pre.1
cluster.4 Juv.2
cluster.4 Comp.4
cluster.4 Adult.3
cluster.5 Adult.2
cluster.6 Pre.5
我想计算第一列中输入的次数,然后将其打印到新的第三列,以便输出看起来像这样。
cluster.1 Adult.1 1
cluster.2 Comp.1 1
cluster.3 Adult.2 2
cluster.3 Pre.3 2
cluster.4 Pre.1 4
cluster.4 Juv.2 4
cluster.4 Comp.4 4
cluster.4 Adult.3 4
cluster.5 Adult.2 1
cluster.6 Pre.5 1
最后我计划从我的文件中删除那些行,其中第3列等于1但是认为它可能是一个两步过程。感谢。
答案 0 :(得分:5)
使用join
:
cut -f1 input | sort | uniq -c | sed 's/^ *\([0-9]*\) */\1\t/' | \
join -t $'\t' -1 2 -2 1 -o '2.1 2.2 1.1' - input
输出:
cluster.1 Adult.1 1
cluster.2 Comp.1 1
cluster.3 Adult.2 2
cluster.3 Pre.3 2
cluster.4 Pre.1 4
cluster.4 Juv.2 4
cluster.4 Comp.4 4
cluster.4 Adult.3 4
cluster.5 Adult.2 1
cluster.6 Pre.5 1
答案 1 :(得分:5)
使用awk
,您可以按如下方式读取文件两次:
$ awk 'NR==FNR {a[$1]++; next} {print $0, a[$1]}' file file
cluster.1 Adult.1 1
cluster.2 Comp.1 1
cluster.3 Adult.2 2
cluster.3 Pre.3 2
cluster.4 Pre.1 4
cluster.4 Juv.2 4
cluster.4 Comp.4 4
cluster.4 Adult.3 4
cluster.5 Adult.2 1
cluster.6 Pre.5 1
第一次由NR==FNR
陈述并计算该项目。第二次是第二个{}
块并打印该行和计数器。
答案 2 :(得分:3)
Perl解决方案:
#!/usr/bin/perl
use warnings;
use strict;
sub output {
my $buffer_ref = shift;
print "$_\t", 0 + @$buffer_ref, "\n" for @$buffer_ref;
}
my $previous_cluster = q();
my @buffer;
while (<>) {
chomp;
my ($cluster, $val) = split /\t/;
if ($cluster ne $previous_cluster) {
output(\@buffer);
undef @buffer;
$previous_cluster = $cluster;
}
push @buffer, $_;
}
# Do not forget to output the last cluster.
output(\@buffer);
答案 3 :(得分:2)
使用关联数组的Bash解决方案:
declare -A array
while read col1 col2 ; do
((array[$col1]++))
done < "$infile"
while read col1 col2 ; do
echo -e "$col1\t$col2\t${array[$col1]}"
done < "$infile"
输出:
cluster.1 Adult.1 1
cluster.2 Comp.1 1
cluster.3 Adult.2 2
cluster.3 Pre.3 2
cluster.4 Pre.1 4
cluster.4 Juv.2 4
cluster.4 Comp.4 4
cluster.4 Adult.3 4
cluster.5 Adult.2 1
cluster.6 Pre.5 1