conta o número de ocorrências de substring e mantém a maior pontuação

2

Eu tenho uma lista de string como:

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

e eu quero filtrar as duplicatas, imprima o número de ocorrências (da subseqüência que pode ser de comprimento diferente, mas será delimitada por ^ (início da string) de um lado, \ tab por outro) mais somente impressão o maior número encontrado associado à string, ou seja, eu quero que a saída seja algo como (a string, o número de ocorrências e o score também podem aparecer em uma ordem diferente):

3 83 StringA
3 98 StrinB
1 65 StringC

Entendo que posso usar uma combinação de sort e uniq para classificar as mesmas ocorrências e remover duplicatas, mas isso não considera "pontuações" diferentes. Eu estou querendo saber como eu posso classificar, ignorando as pontuações e, em seguida, filtrar as duplicatas, mantendo o controle da maior pontuação.

    
por cerr 06.07.2018 / 06:13

4 respostas

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

Explicação

  1. %código%
    • datamash -sg 1 count 1 max 2 < input.txt - ordena a entrada antes do agrupamento; isso elimina a necessidade de canalizar manualmente a entrada por meio de -s .
    • sort - agrupar por primeira coluna.
    • -g 1 - conta o número de elementos no grupo.
    • count 1 - imprime o valor máximo da segunda coluna para cada grupo.
  2. max 2 - rearranjo de campos.

Resultado

3 98 StrinB
3 83 StringA
1 65 StringC
    
por 06.07.2018 / 18:27
6

isso pode ser feito por 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
    
por 06.07.2018 / 07:55
2

Tente,

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

  • -k2 classificará o segundo campo.

  • -rk1 inverterá a ordenação do primeiro campo.

  • -f1 ignorará o primeiro campo até para verificar a exclusividade

por 06.07.2018 / 06:40
1

Eu escrevi um pequeno script perl se essa opção funcionar para você conseguir o que deseja

#!/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 hash conterá o número de ocorrências de cada string

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

%max conterá pontuação máxima para cada string

   $VAR1 = {
               'StrinB' => 98,
               'StringC' => '65',
               'StringA' => 83
             };
    
por 06.07.2018 / 07:39