awk: Posso encontrar a ocorrência de char na string dada?

1

Existe alguma maneira de obter o resultado a seguir?

a c a c a c a a a a a a a a c c c a c 0 0 a c 0 a

max a
2nd max c
    
por MOHASIN 27.11.2015 / 12:57

5 respostas

1

Isso faz isso:

echo "a c a c a c a a a a a a a a c c c a c 0 0 a c 0 a"|tr " " "\n"|sort|uniq -c|sort -rn
  1. Usamos tr para converter os espaços em novas linhas e, em seguida,
  2. use sort para classificar os dados (que agora são uma série de linhas) em ordem alfabética e, em seguida,
  3. use uniq para contar quantos há de cada e, por último,
  4. use sort novamente para alterar a ordem de apresentação para descendente (com ocorrências máximas primeiro).

Ele assume que cada item é separado por um único espaço (o que é verdadeiro em seu exemplo).

    
por 27.11.2015 / 13:03
1

tente

echo "i u v w a c a c a c a a a a a a a a c c c a c 0 0 a c 0 a"|
  awk 'BEGIN { RS=" " ; } 
       {a[$1]++;} 
       END { 
           PROCINFO["sorted_in"] = "@val_num_desc" ;
           asorti(a,b) ; 
          i = 1 ; 
          for (aa in a ) {
              printf "%d : %s =%d\n",i++,aa,a[aa] ;
              if ( i == 3 ) exit ;} }'

(pode ser onelined)

onde

  • BEGIN { RS=" " ; } definir separador de campos
  • PROCINFO["sorted_in"] = "@val_num_desc" ; sort de acordo com o valor da matriz

você pode adicionar for (aa in a ) printf "a[%s]=%d\n",aa,a[aa] ; antes de PROCINFO para ver a ordem real da matriz antes de classificá-la.

    
por 27.11.2015 / 16:01
0

Eu ficaria tentado a buscar ruby aqui:

echo "a c a c a c a a a a a a a a c c c a c 0 0 a c 0 a" |
ruby -e '
  max = STDIN.gets                                # read the line
             .split                               # split on whitespace
             .group_by {|elem| elem}              # create a hash grouping the words
             .to_a                                # convert has to array of [key,value] pairs
             .map {|key, val| [key, val.length]}  # convert to array of [key, count] pairs
             .sort_by {|key, count| count}        # sort numerically
             .reverse                             # in descending order
  puts "max: " + max[0][0]
  puts "2nd max: " + max[1][0]
'
    
por 27.11.2015 / 15:34
0

Em perl :

#!/usr/bin/env perl
use strict;
use warnings;

my %count_of;
#split the first line of input on whitespace - count each element. 
$count_of{$_}++ for split (' ', <> ); 

#sort by count, print in order. 
foreach my $letter ( 
    sort { $count_of{$b} <=> $count_of{$a} } 
        keys %count_of ) {
    print $count_of{$letter}, " => ", $letter,"\n";
}

Isso pode ser feito com uma linha:

perl -lne '$c{$_}++ for split; END{print join ( "\n", (sort{$c{$b}<=>$c{$a}} keys %c )[0,1])}'
    
por 27.11.2015 / 16:13
0

Se for awk ( file contém a "string"):

awk 'BEGIN{RS=" "} {a[$1]++} END{for(i in a){if(a[i]>m){m=a[i];f=i}else 
  if(a[i]>n){n=a[i];s=i}}print "max:",f,"\n2nd max:",s}' file
  • BEGIN{RS=" "} define o separador de linha de awk para o espaço.
  • a[$1]++ preenche uma matriz a com os valores como indexados e o número de ocorrências como valores.
  • END{...} O bloco END é executado depois que todas as linhas são processadas.
    • for(i in a) faz um loop no array a .
    • if(a[i]>m) se o valor for maior que m then ...
    • m=a[i];f=i m está definido para esse valor e f para a cadeia. Desta forma, encontramos o valor máximo
    • else if(a[i]>n){...} : agora fazemos o mesmo novamente para o segundo valor máximo e salvá-lo na variável s .
  • print ... No final, imprima a saída no formato desejado.

A saída:

max: a
2nd max: c
    
por 27.11.2015 / 14:21

Tags