部分文字列の発生回数を計算し、最高スコアを維持します。

部分文字列の発生回数を計算し、最高スコアを維持します。

次の文字列のリストがあります。

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}'

  • -k22番目のフィールドがソートされます。

  • -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列目の最大値を出力します。
  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
             };

関連情報