使用perl / linux计算特定列中的重复项

我有一个文件(制表符分隔)与6列(这里为了简单起见,我已经显示了2列)

46_#1 A 47_#1 B 49_#1 C 51_#1 D 51_#1 E 

我想计算第一列中的重复项(只计数 – 不移除)并将计数存储在下一列中。 所以输出应该是 –

 46_#1 1 A 47_#1 1 B 49_#1 1 C 51_#1 2 D 51_#1 2 E 

我已经使用了linux命令 –

 uniq -c file 

但这将采取整个行(不是第一列),然后我使用

 uniq -c -w5 file 

但是第一列的字数可能会有所不同。

任何人都可以帮忙吗?

PS-我有一个非常大的文件(大约1GB)。

我不喜欢提供完整的解决方案,但它似乎是解释最简单的方法。 该程序通过文件读取两次:首先累积频率信息,然后输出修改后的数据。

 use strict; use warnings; @ARGV or die "No input file specified"; open my $fh, '<', $ARGV[0] or die "Unable to open input file: $!"; my %count; while (<$fh>) { next unless my ($key) = split; $count{$key}++; } seek $fh, 0, 0; while (<$fh>) { chomp; next unless my ($key, $rest) = split ' ', $_, 2; print "$key $count{$key} $rest\n"; } 

假设文件被排序,你可以简单的命令来做到这一点:

 sorin@sorin: $ join -1 1 -2 2 -o1.1,2.1,1.2 sample.txt <(cut -f1 sample.txt | uniq -c) 46_#1 1 A 47_#1 1 B 49_#1 1 C 51_#1 2 D 51_#1 2 E 
  • 加入 – 基于共同字段加入文件
    • -1 1 -2 2基于来自第一文件的第一列和第二文件的第二列加入
    • -o1.1,2.1,1.2选择要输出的列
    • <()进程替换 – 进程的输出变成输入文件
    • 加入忽略uniq输出的领先空间
  • 剪切 – 只提取一个字段

注意:如果这些文件没有排序,那么使用之前的回答可能会更好,正如我从您的评论中看到的那样,重复的内容很远