Question

Je devais faire une division dans le script shell et la meilleure façon était:

result1=`echo "scale=3; ($var1 / $total) * 100"| bc -l`
result2=`echo "scale=3; ($var2 / $total) * 100"| bc -l`

mais je veux comparer les valeurs de $result1 et $result2

Utilisation if test $result1 -lt $result2 ou if [ $result1 -gt $result2 ] n'a pas fonctionné: (

Toute idée comment faire?

Était-ce utile?

La solution

Vous pouvez comparer les nombres à virgule flottante en utilisant expr(1):

: nr@yorkie 3724 ; expr 3.1 '<' 3.3
1
: nr@yorkie 3725 ; expr 3.1 '<' 3.09
0

Vous pouvez également bc faire les comparaisons ainsi que les calculs:

if [ "$(echo $result1 '<' $result2 | bc -l)" -eq 1 ];then ... fi

Enfin, ksh93 peut faire l'évaluation arithmétique $(($result1 < $result2)) avec des nombres à virgule flottante, bien que bash ne peut pas.

Autres conseils

Notez que tu dois être un peu prudents en traitant avec des nombres à virgule flottante et si vous testez pour l'égalité que vous voulez vraiment décider une certaine précision et comparer en utilisant cela. Quelque chose comme:

if (abs(x1-x2) < 0.0001) then equal # pseudo-code

la raison étant que les ordinateurs dont nous traitons avec des fractions binaires précision limitée pas vrai reals mathématiques. Limiter la précision en Colombie-Britannique à l'échelle = 3 aura cet effet.

Je voudrais aussi vous déconseillons d'essayer de faire ce genre de choses dans le script shell. Ce n'est pas que vous ne pouvez pas le faire, mais vous devrez bifurquer beaucoup de petites commandes de sous pour faire les bits difficiles et c'est lent à exécuter et généralement une douleur à écrire - vous passez la plupart de votre temps à essayer d'obtenir la coquille de faire ce que vous voulez plutôt que d'écrire le code que vous voulez vraiment. Laissez tomber dans un langage de script plus sophistiqué à la place; ma langue de choix est perl, mais il y a d'autres. comme ça ...

echo $var1 $var2 $total | perl -ne 'my ($var1, $var2, $tot) = split /\s+/; if ($var1/$tot == $var2/$tot) { print "equal\n"; }'

note également que vous divisant par la même valeur ($ au total dans votre question) si la comparaison entière peut se faire contre les numérateurs (var1 et var2) a fourni $ au total est positif

Publier une nouvelle réponse car je ne peux pas encore commenter ...

@Norman réponse de Ramsey n'est pas tout à fait exact:

  • expr effectuera une comparaison entière ou une chaîne, pas une comparaison en virgule flottante.
    Voici ce que la page de l'homme dit:

      

    {expr1 =,>,> =, <, <=,! =} Expr2

         

    retour les résultats de comparaison de nombre entier si les deux arguments sont des nombres entiers; sinon, renvoie les résultats de comparaison de chaînes en utilisant la séquence de classement spécifique à la localisation.

    (juste essayer expr 8.9 '<' 10 et obtenir 0 où il devrait être 1).

  • bcworks grand, mais il est pas toujours installé.


Donc, une autre alternative est d'utiliser perl -e:

  • perl -e 'print expression' imprimera 1 si l'expression est vraie et rien (chaîne vide) autrement.

    par exemple. perl -e 'print 8.9 < 10' -. estampes "1", alors que rien imprime perl -e 'print 2>4'

  • Et quand il est utilisé dans l'instruction if:

    if [ $(perl -e "print $result1 < $result2") ];then ... fi

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top