我有一个字符串列表,例如:
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}'
解释
datamash -sg 1 count 1 max 2 < input.txt
-s
- 分组前对输入进行排序;这消除了手动通过管道输入的需要sort
。-g 1
- 按第一列分组。count 1
- 计算组中元素的数量。max 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 };