operações aritméticas entre arquivos

5

Digamos que eu tenha esses dois arquivos de entrada:

> file1
2
3
4

> file2
10
100
1000

E eu gostaria de calcular: file1 / file2 para cada linha, resultando em file3:

> file 3
0.2
0.03
0.004

As divisões no bash podem ser obtidas por: $((file1_line/file2_line))

    
por dovah 22.08.2016 / 10:58

2 respostas

11

Uma combinação paste e bc é uma boa opção para aritmética simples:

paste -d/ file1 file2 | bc -l

Saída:

.2000000000
.0300000000
.0040000000

Um exemplo mais avançado

Com alguns truques você pode ficar um pouco mais complicado. Diga file3 contém:

6
7
8

Você pode fazer (file1 + file3) / file2 da seguinte forma:

paste -d'(+)/' /dev/null file1 file3 /dev/null file2

Saída:

(2+6)/10
(3+7)/100
(4+8)/1000

Isso funciona porque paste percorre sua lista de delimitadores para cada linha.

Reagir a dividir por zero

As operações do Illigal enviadas para bc resultam em um aviso sendo enviado ao erro padrão. Você poderia redirecioná-los para um arquivo diferente e decidir o fluxo do programa com base em seu conteúdo, por exemplo:

paste -d/ file1 file2 | bc -l > resultfile 2> errorfile
if grep -q 'Divide by zero' errorfile; then
  echo "Error in calculation"
else
  echo "All is well"
fi

Ou se houver algum erro:

paste -d/ file1 file2 | bc -l > resultfile 2> errorfile
if ! file errorfile | grep -q empty; then
  echo "Error in calculation"
else
  echo "All is well"
fi
    
por 22.08.2016 / 11:01
7

comece com

 paste file1 file2 | awk '{printf "%f\n",$1/$2 } '

onde

  • paste irá "mesclar" o arquivo
  • awk calculará a divisão, um de cada vez.

se você não gosta de muitos 0s, apenas adicione

... | sed -e s/0*\$//

para sair em caso de 0

paste file1 file2 | awk '!$2 {exit ; }  {printf "%f\n",$1/$2 } '
    
por 22.08.2016 / 11:02