Je veux comparer une variable à virgule flottante à un entier. Je sais que ce n'est pas la meilleure chose à faire avec bash, mais tout mon script est déjà écrit en bash. $ nombre peut être n'importe quel entier. Si elle est inférieure ou égale à 50, je veux la sortie 1, pour toutes les autres, je veux une sortie avec l'autre variable k. Voici ce que j'ai jusqu'à présent:
number=43
test=$(echo "scale=2; $number/50" | bc -l)
echo "$test"
for k in {1..5}
do
if ["$test" -le 1]
then echo "output"
Elif ["$test" -gt $k]
then echo "output$k"
fi
done
Si j'essaie avec test = 0,43, la première boucle ne fonctionne même pas. Je pense que cela a à voir avec un entier et une comparaison à virgule flottante, mais ne peut pas le faire fonctionner.
Quelque chose me manque?
PS: ce [0.43: command not found
est ce que le terminal sort.
Bash ne peut pas gérer les flotteurs. Dirigez-vous vers bc
à la place:
if [ $(echo " $test > $k" | bc) -eq 1 ]
L'erreur que vous voyez est due au fait que la commande test
(c'est-à-dire la [
) a besoin d'espaces avant et après
Il vaut encore mieux utiliser (( ... ))
puisque vous comparez des nombres comme celui-ci:
if (( $(bc <<< "$test > $k") ))
La partie de la boucle devrait ressembler à ceci:
if (( $(bc <<< "$test <= 1") ))
then
echo "output"
Elif (( $(bc <<< "$test > $k") ))
then
echo "output$k"
fi
Les expressions relationnelles sont évaluées à 0 si la relation est fausse et à 1 si la relation est vraie [ source ]. Notez cependant que c'est un comportement de GNU bc
, et ce n'est pas POSIX
compatible.
Une sorte de vieille question, mais elle porte une réponse supplémentaire je pense.
Bien que la tuyauterie vers une calculatrice de précision supérieure (bc ou dc) fonctionne, cela se fait au prix d'une fourchette et d'un processus supplémentaire, car ces calculatrices ne sont pas intégrées à bash. Une chose qui IS intégré, cependant, est printf
. Donc, si vous pouvez gérer vos nombres dans un nombre particulier de décimales, vous pouvez "faux" virgule flottante comparaisons, avec une fonction comme celle-ci:
#!/usr/bin/env bash
function [[[ () {
local LANG=C lhs rhs
printf -v lhs '%07.3f' "$1"; lhs=${lhs/./}
printf -v rhs '%07.3f' "$3"; rhs=${rhs/./}
case "$2" in
-lt) return $(( ! ( 10#$lhs < 10#$rhs ) )) ;;
-le) return $(( ! ( 10#$lhs <= 10#$rhs ) )) ;;
-eq) return $(( ! ( 10#$lhs == 10#$rhs ) )) ;;
-ge) return $(( ! ( 10#$lhs >= 10#$rhs ) )) ;;
-gt) return $(( ! ( 10#$lhs > 10#$rhs ) )) ;;
esac
}
number=${1:-43}
test=$(dc -e "2k $number 50 / p")
echo "$test"
for k in {1..5}; do
if [[[ "$test" -le 1 ]]]; then
echo "output"
Elif [[[ "$test" -gt "$k" ]]]; then
echo "output $k"
fi
done
Quelques points à considérer ici.
[[[
pour être mignon. Vous pouvez le nommer comme bon vous semble. ntest
ou mynumericcomparison
ou même [[[
.printf
est une fonction interne dans bash, donc malgré le fait qu'elle se trouve sur votre chemin, elle ne coûte pas un fork.printf
.10#
au début de chaque variable à l'intérieur de l'instruction case
est de forcer la comparaison à se produire à la base 10, car un nombre complété par zéro pourrait autrement être interprété comme octal.Voir aussi: http://mywiki.wooledge.org/BashFAQ/022