arithmatic operation in shell script

130 Views Asked by At

My shell script look like this ,

sOneCount =5
sZeroCount=12
aa=`expr $sOneCount / $sZeroCount`
successRate=`expr $aa \* 100

since 5/12 results in 0.416 and then 0.416*100 it should give 41.6 but i am getting "successRate" as 0. Its rounding off the float value.

I want the final result should be 41 like this, please help me in this Thanks

4

There are 4 best solutions below

0
Murphy On

Bash, and probably other similar shells, doesn't support floating point operations:

Evaluation is done in fixed-width integers with no check for overflow

http://man7.org/linux/man-pages/man1/bash.1.html#ARITHMETIC_EVALUATION

You can use bc instead, with the mathlib operations enabled:

$ successRate=$(echo "${sOneCount} / ${sZeroCount} * 100" | bc -l)
$ echo ${successRate}
41.66666666666666666600
0
Ed Morton On

You should be using awk, not shell, for the calculations (and probably whatever else you're doing too but we can't see the rest of your script):

$ cat tst.sh
#!/bin/env bash

sOneCount=$1
sZeroCount=$2

awk -v sOneCount="$sOneCount" -v sZeroCount="$sZeroCount" 'BEGIN{
    aa = (sZeroCount == 0 ? 0 : sOneCount / sZeroCount)
    successRate = aa * 100
    print successRate
    printf "%d\n", successRate
}'

$ ./tst.sh 5 12
41.6667
41

$ ./tst.sh 5 0
0
0

Note that it protects against a divide by zero error.

0
glenn jackman On

Note in the expr man page(1) that the / operator gives you the quotient, implying this is interger-only arithmetic.

You can get the integral successRate by multiplying the numerator by 100 first

$ successRate=$( expr 100 \* "$sOneCount" / "$sZeroCount" )
$ echo "$successRate"
41

Or, in bash, you don't need to call out to expr -- use the builtin arithmetic expression syntax:

$ successRate=$(( 100 * sOneCount / sZeroCount ))
$ echo "$successRate"
41

(1): the man page for the BSD expr on my Mac is more explicit: / returns the result of "integer division" of "integer-valued arguments".

0
karakfa On

You can easily write your own calculator/eval in awk for most basic cases

For example:

$ eval() { awk "BEGIN {print $1}"; }
$ x=4; y=7;
$ eval "$x/$y"
0.571429

$ rate=$(eval "$x/$y")
$ eval "$rate*100"
57.1429

or, with a slight change can accept more arguments

$ eval() { awk "BEGIN {print $*}"; }
$ eval "$x" / "$y" "*" 100
57.1429