web-dev-qa-db-fra.com

Faire des calculs simples sur la ligne de commande en utilisant les fonctions bash: $ 1 divisé par $ 2 (en utilisant peut-être bc)

Parfois, je dois diviser un nombre par un autre. Ce serait génial si je pouvais simplement définir une fonction bash pour cela. Jusqu'à présent, je suis obligé d'utiliser des expressions comme

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

mais ce serait génial si je pouvais définir une fonction .bashrc qui ressemblait à

divide () {
  bc -d $1 / $2
}
33
ixtmixilix

J'ai une fonction bash pratique appelée calc:

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

Exemple d'utilisation:

$ calc 65320/670
97.49253731343283582089

$ calc 65320*670
43764400

Vous pouvez changer cela pour vous. Par exemple:

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

Remarque: <<< est un ici chaîne qui est introduit dans le stdin de bc. Vous n'avez pas besoin d'appeler echo.

45
dogbane

Bash peut faire le calcul lui-même dans une certaine mesure. Ce n'est pas utile pour la précision, cependant, car il arrondit.

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

Mais vous avez parfaitement raison - une fonction bash serait un simple raccourci et votre exemple fonctionne essentiellement.

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

Jetez cela dans votre .bashrc et vous pourrez alors:

[user]$ divide 10 5
2.0000000000000000000000000
20
rjewell

Vous connaissez probablement le bash builtin 'expr' comme dans

$ expr 60 / 5
12

qui est limité aux entiers et a besoin des espaces entre les arguments.

Qu'est-ce qui vous empêche de définir une fonction dans le sens de l'expression d'écho que vous utilisez déjà? C'est à dire.

 divide () {
   echo $1/$2 | bc
 }
9
Tatjana Heuser

Pas vraiment une réponse à cette question précise, mais il pourrait être bon de savoir. Utilisez zsh ;-)

% echo $((65320./670))
97.492537313432834
7
Stéphane Gimenez

Si vous avez calc installé sur votre système et que vous n'aimez pas l'arrondi, vous pouvez:

div() { calc "$1 / $2"; }
2
user13742

Un hack sale pour les petites valeurs et une précision limitée sans utiliser bc serait, pour multiplier le nominateur avant la division, pour obtenir un résultat précis.

Exemple sans précision:

echo $((13/7)) 
1

et avec une précision à 2 chiffres: multipliez par 100 et déplacez la virgule décimale de 2 pas vers la gauche:

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

Cela n'est utile que si la plage de nombres est connue auparavant et que la précision est toujours la même. Éviter d'appeler bc, et d'appeler sed ne semble pas très raisonnable.

Notez que la multiplication des valeurs peut entraîner des erreurs de débordement, mais pas très tôt:

echo $((1000000000*12345678901))
-6101065172709551616
2
user unknown

Au lieu d'utiliser bc, vous pouvez utiliser awk:

div() { awk -v p=$1 -v q=$2 'BEGIN{print p/q}'; }
0
jfg956