次の文字列のリストがあります。
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
2番目のフィールドがソートされます。-rk1
最初のフィールドを逆順に並べ替えます。-f1
無視されますに従って最初のフィールドの一意性を確認してください。
答え3
datamash -sg 1 count 1 max 2 < input.txt | awk '{print $2, $3, $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 };