views:

499

answers:

4

I know it's really stupid question, but I don't know how to do this in bash:

20 / 30 * 100

It should be 66,67 but expr is saying 0, because it doesn't support float. What command in Linux can replace expr and do this equalation?

+4  A: 

bc will do this for you, but the order is important.

> echo "scale = 2; 20 * 100 / 30" | bc
66.66
> echo "scale = 2; 20 / 30 * 100" | bc
66.00

or, for your specific case:

> export ach_gs=2
> export ach_gs_max=3
> x=$(echo "scale = 2; $ach_gs * 100 / $ach_gs_max" | bc)
> echo $x
66.66

Whatever method you choose, this is ripe for inclusion as a function to make your life easier:

#!/bin/bash
function pct () {
    echo "scale = $3; $1 * 100 / $2" | bc
}

x=$(pct 2 3 2) ; echo $x # gives 66.66
x=$(pct 1 6 0) ; echo $x # gives 16
paxdiablo
but i want to do this in script, the full line is :$ach_gs / $ach_gs_max * 100
maxorq
something less complicated?
maxorq
not more complicated, easier to remember!
maxorq
@maxorq: You might note that in all examples others have given, the multiplication is done first. This is a scientific computing thing -- since we know there are more digits available to the left of the decimal place than to the right, multiplication goes first to minimize loss of precision due to rounding.
Conspicuous Compiler
I just want to get percent of completed. 20 done, max 30
maxorq
+1  A: 

As reported in the bash man page:

The shell allows arithmetic expressions to be evaluated, under certain circumstances...Evaluation is done in fixed-width integers with no check for overflow, though division by 0 is trapped and flagged as an error.

You can multiply by 100 earlier to get a better, partial result:

let j=20*100/30
echo $j

66

Or by a higher multiple of 10, and imagine the decimal place where it belongs:

let j=20*10000/30
echo $j

66666

Conspicuous Compiler
bash: let: 17375_AntiTetris: value too great for base (error token is "17375_AntiTetris")
maxorq
It might help if you posted the actual command line you used. (I'm guessing you used more zeroes than I did.) I executed the commands above before I posted, and got the results given. Please try those first.
Conspicuous Compiler
let j=20 * 100 / 30
maxorq
Huh, odd, I don't remember putting spaces in there originally. Anyhow, try removing your spaces and repeat. I edited my post to remove the problematic whitespace.
Conspicuous Compiler
A: 

just do it in awk

# awk 'BEGIN{print 20 / 30 * 100}'
66.6667

save it to variable

# result=$(awk 'BEGIN{print 20 / 30 * 100}')
# echo $result
66.6667
ghostdog74
A: 

I generally use perl:

perl -e 'print 10 / 3'
pgl