Encontrando o máximo dos valores em um arquivo

5

Eu tenho um arquivo que contém vários números, como segue.

21 12 33 35 21 12 33 44 52 63 14 12 23 34 11 12 13 53 1 12 43 33 44

Como posso encontrar o máximo desses valores, que é 63 ? Eu queria usar stats , mas parece que esse comando não existe na minha máquina e não quero instalá-lo. Como posso abordar usando perl ?

    
por AFP 19.05.2014 / 07:51

10 respostas

7

Usando List::Util (parte da biblioteca padrão desde 5.8, caso contrário, disponível no CPAN):

perl -MList::Util=max -lane 'print max(@F)'
    
por 19.05.2014 / 08:13
16

Outras respostas são muito legais e Perl / awk é o caminho a percorrer.

Apenas por diversão, você também pode usar isso (assumindo o GNU grep ):

$ grep -Eo '[0-9]+' file | sort -rn | head -n 1
63

Explicação

  • grep -Eo '[0-9]+' file imprime todas as correspondências de números inteiros positivos decimais no arquivo. Cada correspondência será impressa em uma linha diferente, conforme o sinal -o .
  • sort -rn ordena a lista numericamente e ao contrário, para que o primeiro número seja o maior.
  • head -n 1 imprime a primeira linha.

Por etapas:

$ grep -Eo '[0-9]+' file
21
12
33
35
21
12
33
44
52
63
14
12
23
34
11
12
13
53
1
12
43
33
44
$ grep -Eo '[0-9]+' file | sort -rn 
63
53
52
44
44
43
35
34
33
33
33
23
21
21
14
13
12
12
12
12
12
11
1
    
por 19.05.2014 / 12:02
8

Estou ciente de que isso não é perl:

awk '{for(i=1;i<=NF;i++) if($i>maxval) maxval=$i;}; END { print maxval;}' file
    
por 19.05.2014 / 07:57
3

Outra solução perl :

$ perl -MList::Util=max -anle 'print max(@F)' file 
63

Isso funcionará com o arquivo contendo uma linha, se você tiver várias linhas no arquivo e quiser encontrar o valor máximo em todas as linhas, tente:

$ perl -MList::Util=max -alne '$tmp = max @F; $max = $tmp if $max < $tmp; END { print $max }'
    
por 19.05.2014 / 08:15
3

Isso funciona no Ubuntu, mas não no MacOS:

echo "21 12 33 35 21 12 33 44 52 63 14 12 23 34 11 12 13 53 1 12 43 33 44" | grep -oE "[0-9]*" | sort -nr | head -n 1

Primeiro, grep para os padrões que correspondem a um número (add., se você tiver decimais), então, classifique numérico na ordem inversa e, em seguida, escolha o primeiro resultado.

    
por 19.05.2014 / 09:43
3

Aqui está uma abordagem Perl mais rápida que não requer classificação:

$ echo '21 12 33 35 21 12 33 44 52 63 14 12 23 34 11 12 13 53 1 12 43 33 44' |
    perl -lane 'map{$m=$_ if $_>$m}@F; print $m'

ou, como sugerido por @Gnouc nos comentários:

$ echo '21 12 33 35 21 12 33 44 52 63 14 12 23 34 11 12 13 53 1 12 43 33 44' |
    perl -lane '$m<$_ and $m=$_ for @F; print $m'
    
por 19.05.2014 / 17:09
2

Se você quisesse suportar diferentes tipos de números (-2, 1E-20, inf, 0x2f, 0b0101, 0777 ...), e não apenas números inteiros decimais positivos, você poderia fazer:

perl -lne '
  while (m{(?!<\w)(?:(0x[0-9a-f]+|
            0b[01]+|
            0[0-7]+)|
           [-+]?(\d+(\.\d*)?|\.\d+)(e[-+]?\d+)?|
           infinity|inf)(?!\w)}xgi) {
    $v = defined($1) ? oct($1) : $&;
    $m = $& unless defined($m) && $m >= $v
  }
  END {print $m if defined $m}'
    
por 09.12.2014 / 15:28
1

Não há necessidade de awk, grep ou perl.

{ 
    for n in 21 12 33 35 21 12 33 44 52 63 14 12 23 34 11 12 13 53 1 12 43 33 44
    do 
        echo $n
    done 
} | sort | tail -n1
    
por 19.05.2014 / 15:03
0

Sim, isso não é perl , mas eu gosto do GNU awk para isso

awk -v RS='[[:space:]]+' 'BEGIN{max=-inf};{max = $0>max? $0: max};END{print max}' file
63
    
por 09.12.2014 / 16:21
-1
grep '[0-9]*' number.sh | sort -rn | head -1
    
por 09.12.2014 / 03:42