다음과 같은 문자열 목록이 있습니다.
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 };