Matemática com shell script

Em um terminal Linux, caso você deseje somar 20 e 5 digitando simplesmente “20+5”, isso resulta em um “comando não encontrado”. Para fazer um cálculo na linha de comando é necessário usar o comando “expr” ou a sintaxe $((operações)). Veja esses exemplos, alguns usando variáveis:

$ expr 20 + 05
$ expr 20 \* 5 # Asterisco é caractere especial, por isso a barra antes
$ expr "$a" + "$num"
$ expr length "Monolito Nimbus" # Conta o número de caracteres do que tiver entre aspas
$ var=$((20+5))
$ soma=$((var+2-outra_var))

O Bash (assim como o sh, ash, csh) não possui suporte nativo para operações com ponto flutuante, sendo necessário o uso de comandos externos. Um desses comandos é o bc: uma linguagem para cálculos, permitindo realizar cálculos matemáticos através do terminal – e, assim, automatizar alguns processos. Dentre as principais operações estão:

  • adição (+)
  • subtração (-)
  • multiplicação (*)
  • divisão (/)
  • resto da divisão (%)
  • raiz quadrada (sqrt)
  • potência (^)
  • seno (s(x))
  • cosseno (c(x))
  • logaritmo natural ln (l(x))
  • função exponencial (e(x))

Veja alguns exemplos, alguns usando variáveis – “scale” define o número de casas decimais:

$ echo "(20+5)/5" | bc
$ echo '100.098*(1+0.22)' | bc
$ echo "scale=2;($lat1+$lat2)/2" | bc # onde lat1=-23.6855443 e lat2=-23.6555284
$ lat_med=$(bc <<< "scale=7;($lat1+$lat2)/2")

Às vezes, pode aparecer um erro do tipo “valor muito grande para esta base de numeração (token com erro é “008”)”. Isso acontece porque o bash considera números que iniciam com zero como estando na base 8 (portanto, não podem ter dígitos maiores que 7). Para indicar que o valor é decimal, use “10#” na frente da variável (incluir “$” mesmo quando estiver dentro de parênteses). Por exemplo:

echo $((10#$a+10#$b))

Caso apareça um erro do tipo “erro de sintaxe: operador aritmético inválido (token com erro é” ou “(standard_in) 1: illegal character: ^M”, é porque tem algum caractere não-numérico na variável utilizada (^M, por exemplo). Para isso, imprima essa variável e dê um pipe em sua saída para o seguinte comando e eliminar esses caracteres:

echo $a | sed $'s/[^[:print:]\t]//g'

Os ângulos são dados em radianos. É possível criar uma função que converta de graus para radianos:

pi = 3.14159265
define d2r(n) { return n * (pi/180); }

Da mesma forma, pode-se definir uma função para passar o logaritmo da base e para base 10:

define l10(x) {return l(x)/l(10)}

O bc pode ser utilizado diretamente no terminal (comando “bc” ou “bc -l”, que que ativa uma biblioteca de operações matemáticas) ou em shell script com a seguinte estrutura: variavel=$(echo “expressão” | bc). Veja esse script com dois exemplos: uma comparação, que retorna 1 para verdadeira e 0 como falsa, e uma divisão seguida de multiplicação (o parâmetro “scale” define o número de casas decimais):

var=`echo "$observado > $previsto" | bc`
if [ "$var" -eq 1 ]; then
	assertividade=`echo "scale=3 ; $previsto / $observado * 100" | bc`
else
	assertividade=`echo "scale=3 ; $observado / $previsto * 100" | bc`
fi
echo "Assertividade - "$assertividade

Veja mais no artigo BC: A sua calculadora programável no Linux e alguns exemplos de uso do “if” no canivete suíço de Shell Script.

One comment

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.