Fazendo cálculos simples na linha de comando usando funções bash: $ 1 dividido por $ 2 (usando bc talvez)

31

Às vezes, preciso dividir um número por outro. Seria ótimo se eu pudesse definir uma função bash para isso. Até agora, sou forçado a usar expressões como

echo 'scale=25;65320/670' | bc

mas seria ótimo se eu pudesse definir uma função .bashrc que se parecesse com

divide () {
  bc -d $1 / $2
}
    
por ixtmixilix 31.01.2012 / 15:12

8 respostas

43

Eu tenho uma útil função bash chamada calc :

calc () {
    bc -l <<< "$@"
}

Exemplo de uso:

$ calc 65320/670
97.49253731343283582089

$ calc 65320*670
43764400

Você pode mudar isso para se adequar a si mesmo. Por exemplo:

divide() {
    bc -l <<< "$1/$2"
}

Observação: <<< é uma string que é fornecida no stdin de bc . Você não precisa invocar echo .

    
por 31.01.2012 / 17:32
18

Bash pode fazer as contas em si até certo ponto. Não é útil para a precisão, no entanto, à medida que gira.

[user]$ echo $(( 10/5 ))
2

Mas você está exatamente certo - uma função bash seria um atalho simples e seu exemplo basicamente funciona.

divide() {
  echo "scale=25;$1/$2" | bc
}

Jogue isso no seu .bashrc e então você pode:

[user]$ divide 10 5
2.0000000000000000000000000
    
por 31.01.2012 / 15:18
9

Você provavelmente conhece o bash construído 'expr' como em

$ expr 60 / 5
12

que é limitado a números inteiros e precisa dos espaços entre os argumentos.

O que impede você de definir uma função nos moldes da expressão de eco que você já está usando? Ou seja,

 divide () {
   echo $1/$2 | bc
 }
    
por 31.01.2012 / 15:43
7

Não é realmente uma resposta para essa pergunta precisa, mas pode ser bom saber. Use zsh ; -)

% echo $((65320./670))
97.492537313432834
    
por 31.01.2012 / 19:12
2

Se você tem calc instalado em seu sistema e não gosta de arredondamentos, é possível:

div() { calc "$1 / $2"; }
    
por 31.01.2012 / 17:32
2

Um hack sujo para valores pequenos e uma precisão limitada sem usar bc seria, para multiplicar o nominador antes da divisão, para obter um resultado preciso.

Exemplo sem precisão:

echo $((13/7)) 
1

e com precisão de 2 dígitos: multiplique por 100 e mova o ponto decimal 2 passos para a esquerda:

echo $((100*13/7)) | sed 's/..$/.&/'
1.85
echo $((100*13/7))%
185%

Isso só é útil se o intervalo de números for conhecido antes e a precisão for sempre a mesma. Evitar chamar bc e chamar sed não parece muito razoável.

Note que multiplicar os valores pode levar a erros de estouro, mas não muito cedo:

echo $((1000000000*12345678901))
-6101065172709551616
    
por 01.02.2012 / 00:51
0

Em vez de usar bc, você pode usar o awk:

div() { awk -v p=$1 -v q=$2 'BEGIN{print p/q}'; }
    
por 06.02.2012 / 22:12
-4
echo Division
efgh=$num1/$num2
remainder=$num1%num2
echo $num1 "/" $num2 "=" $efgh.$remainder
echo
    
por 01.03.2016 / 02:09