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


33

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

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

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

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

Réponses:


45

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

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

Exemple d'utilisation:

$ calc 65320/670
97.49253731343283582089

$ calc 65320*670
43764400

Vous pouvez changer cela à votre guise. Par exemple:

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

Remarque: <<< est une chaîne here qui est introduite dans le stdin de bc. Vous n'avez pas besoin d'invoquer echo.


3
Je conviens que le résultat est meilleur sans écho supplémentaire, mais comme il s'agit d'un shell intégré, il ne génère que peu, voire aucun coût supplémentaire. Ce qui m'empêche d'utiliser '<<<' dans les fonctions du shell, c'est sa limitation à bash, alors que l'écho supplémentaire permet de l'utiliser dans le shell ou le ksh d'origine sans modifications.
Tatjana Heuser le

@TatjanaHeuser ksh, la variante 93, supporte les chaînes ici.
Kusalananda

Pour assigner une variable, j'ai fait ceci: foo = $ (bc -l <<< "(2 * 5) + 5")
thebiggestlebowski

20

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 tout à fait raison: une fonction bash serait un simple raccourci et votre exemple fonctionne en principe.

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

Jetez cela dans votre .bashrc et ensuite vous pourrez:

[user]$ divide 10 5
2.0000000000000000000000000

1
echo $((10 / 5))n'a besoin d'aucune citation.
utilisateur inconnu le

1
Désagrément significatif: echo $((6383/7671)) vous donnera zéro. Vous devez être explicite sur les nombres en virgule flottante:echo $((6383.0/7671.0))
Sridhar Sarnobat le

9

Vous connaissez probablement le bash construit 'expr' comme dans

$ expr 60 / 5
12

qui est limité à des entiers et nécessite les 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
 }

1
juste l'ignorance. Je ne savais pas que je pouvais le faire fonctionner de cette façon ...
ixtmixilix

7

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

% echo $((65320./670))
97.492537313432834

En fait, je cherchais cette question parce que je changeais pour zsh et ne pouvais pas utiliser le mode exprintégré de bash , donc bonne réponse quand même :)
Steen Schütt

2

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

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

hmm ... impossible de trouver un paquet debian pour 'calc'
ixtmixilix le

Le paquet s'appelle apcalc (Précision arbitraire) ... Le binaire s'appellecalc
Peter.O

@ Peter.O Ok, dans le dépôt Arch Linux, il est appelé calc.

2

Un bidouillage sale pour les petites valeurs et une précision limitée sans utiliser bc serait de 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 de 2 chiffres: multipliez par 100 et déplacez le point décimal de 2 pas à gauche:

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

Ceci 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 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

L'utilisation de doubles parenthèses pour évaluer les expressions mathématiques est obsolète. Utilisez: à la $[expression]place
laebshade

3
@laebshade: Je peux vous prouver le contraire, l'inverse est vrai. Voici une citation du manuel bash:The old format $[expression] is deprecated and will be removed in upcoming versions of bash.
utilisateur inconnu

Également discuté ici ,  ici  et  ici .
G-Man dit 'Réintégrez Monica' le

0

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

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

-4
echo Division
efgh=$num1/$num2
remainder=$num1%num2
echo $num1 "/" $num2 "=" $efgh.$remainder
echo
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.