计算子串出现的次数并保留最高分

计算子串出现的次数并保留最高分

我有一个字符串列表,例如:

StringA  45
StrinB  98 
StringA  35
StringA  83
StrinB  78
StringC  65
StrinB  98

我想过滤掉重复项,打印出现的次数(子字符串的长度可以不同,但​​一侧由 ^(字符串开头)分隔,另一侧由 \tab 分隔)加上仅打印最高的数字发现与字符串相关联,即我希望输出类似于(字符串、出现次数和分数也可以以不同的顺序出现):

3 83 StringA
3 98 StrinB
1 65 StringC

sort我知道我可以使用和的组合来uniq对相同的事件进行排序并删除重复项,但这不会考虑不同的“分数”。我想知道如何在忽略分数的情况下进行排序,然后在跟踪最高分数的同时过滤掉重复项。

答案1

这可以自己完成awk

awk '{ max[$1]=( max[$1]>$2?max[$1]:$2 ); seen[$1]++ } 
    END{ for (x in seen) print seen[x], max[x], x }' infile
3 98 StrinB
3 83 StringA
1 65 StringC

答案2

尝试,

awk '{print $2" "$1}' file.txt | sort -k2 -rk1 | uniq -f1 -c | awk '{print $3" "$1" "$2}'

  • -k2将对第二个字段进行排序。

  • -rk1将反向排序第一个字段。

  • -f1将忽略取决于检查唯一性的第一个字段

答案3

datamash -sg 1 count 1 max 2 < input.txt | awk '{print $2, $3, $1}'

解释

  1. datamash -sg 1 count 1 max 2 < input.txt
    • -s- 分组前对输入进行排序;这消除了手动通过管道输入的需要sort
    • -g 1- 按第一列分组。
    • count 1- 计算组中元素的数量。
    • max 2- 打印每组第二列的最大值。
  2. awk '{print $2, $3, $1}'- 重新排列字段。

输出

3 98 StrinB
3 83 StringA
1 65 StringC

答案4

我写了一个小的 perl 脚本,如果这个选项适合你来实现你想要的

#!/usr/bin/perl  
my (%max,%count);
open(my $fh,'<',"<INPUT FILE>");  #open input file for reading
while(my $line = <$fh>){. 
        my ($string,$score) = split(' ',$line);
        $count{$string}++;       
        if(defined $max{$string}){
                if($score > $max{$string}){
                        $max{$string} = $score;
                }
        }
        else{
                $max{$string} = $score;
        }
}
for my $string ( keys%max){
        print "$count{$string} $max{$string} $string\n";
}

%count散列将包含每个字符串出现的次数

>    $VAR1 = {
>               'StrinB' => 3,
>               'StringC' => 1,
>               'StringA' => 3
>             };

%max将包含每个字符串的最大分数

   $VAR1 = {
               'StrinB' => 98,
               'StringC' => '65',
               'StringA' => 83
             };

相关内容