Como faço para arredondar números para o inteiro mais próximo a partir da linha de comando?

5

Existe um ficheiro que tenho, que parece

555.92 569.472 582.389 648.078 999.702 1040.75 1386.24 1418.47 1998.26 2182.13 2384.3

Eu precisaria arredondar todos os números como este

556 569 582 

Idealmente, não preciso criar um arquivo tmp. Como fazer isso?

    
por user3069326 23.06.2015 / 13:07

7 respostas

10

Execute o conteúdo do arquivo através da função printf.

 $ xargs -a numbers.txt -n1 printf "%1.f "                                   
    556 569 582 648 1000 1041 1386 1418 1998 2182 2384 

Além disso, o Ubuntu tem um pequeno programa chamado numfmt , que permite formatar números para padrões definidos pelo usuário e legíveis para humanos.

Por exemplo,

$ xargs -a numbers.txt -n1 numfmt  --to=si --round=up | xargs echo 
556 570 583 649 1.0K 1.1K 1.4K 1.5K 2.0K 2.2K 2.4K

Verifique man numfmt para mais informações.

    
por Sergiy Kolodyazhnyy 23.06.2015 / 13:22
5

bash só pode manipular aritmética inteira. Use uma linguagem mais poderosa, por ex. Perl:

perl -ane 'printf "%.0f ", $_ for @F' file
  • -n lê a linha de entrada por linha
  • -a divide cada linha no espaço em branco com a @F array
  • %.0f é um formato de fluxo com zero dígitos após o ponto decimal
por choroba 23.06.2015 / 13:25
5

Outra solução python (one-liner). Executar em um terminal:

python3 -c "[print(round(float(n))) for n in open('f').read().split()]"

Em que 'f' é o arquivo de origem com seus flutuantes, entre aspas simples, por exemplo:

python3 -c "[print(round(float(n))) for n in open('/home/jacob/Bureaublad/test').read().split()]"

Saída:

556
569
582
648
1000
1041
1386
1418
1998
2182
2384

Outra forma de saída

Se você quiser os números em uma linha:

python3 -c "[print(round(float(n)), end=' ') for n in open('f').read().split()]"

(Obrigado @Oli!)

Saída:

556 569 582 648 1000 1041 1386 1418 1998 2182 2384

Explicação

O comando:

python3 -c "[print(round(float(n))) for n in open('f').read().split()]"

nas seções:

open('f').read().split()

lê o arquivo 'f' , o divide em floats (agora ainda como string)

round(float(n))

Primeiro interpreta a string n como float, arredonda para um inteiro

[print(round(float(n))) for n in open('f').read().split()]

finalmente, gera o comando print, para imprimir todos os carros alegóricos.

    
por Jacob Vlijm 23.06.2015 / 14:11
4

Usando python :

#!/usr/bin/env python2
with open('/path/to/file.txt') as f:
    for line in f:
        numbers = line.strip().split(' ')
        for num in numbers:
            print int(round(float(num))),
  • A lista numbers conterá todos os números gravados em espaços ( line.rstrip().split(' ') )

  • Em seguida, usamos a função round() para arredondar os números de ponto flutuante

  • Como as entradas são armazenadas como srings, precisamos usar a função float() para convertê-las em flutuadores

  • A função int() imprimirá o número descartando os pontos decimais, ou seja, somente a parte inteira

Saída:

556 569 582 648 1000 1041 1386 1418 1998 2182 2384
    
por heemayl 23.06.2015 / 13:17
3

Onde está a versão awk ? printf também pode ser usado em awk :

awk '{for(i=1;i<=NF;i++) {printf "%0.f ",$i} printf "\n"}'

ou no local sem um arquivo temporário (Thx @muru )

awk -i inplace '{for(i=1;i<=NF;i++) {printf "%0.f ",$i} printf "\n"}'

Exemplo

% cat foo
555.92 569.472 582.389 648.078 999.702 1040.75 1386.24 1418.47 1998.26 2182.13 2384.3

% awk '{
  for(i=1;i<=NF;i++) {
    printf "%0.f ",$i
  }
  printf "%s","\n"
}' foo
556 569 582 648 1000 1041 1386 1418 1998 2182 2384
    
por A.B. 23.06.2015 / 16:12
2

Usando perl :

perl -ne 'printf("%.0f ", $_) for split' file
    
por Sylvain Pineau 23.06.2015 / 13:29
2

Isso deve funcionar para você:

perl -ne '@l=split(/\s+/,$_); foreach(@l){printf("%.0f",$_); print " "}'

você pode usá-lo como

echo "555.92 569.472 582.389" | perl -ne '
  @l=split(/\s+/,$_);
  foreach(@l) {
    printf("%.0f",$_);
    print " "
  }'
    
por Wayne_Yux 23.06.2015 / 13:22