Preferred way to do arithmetic in bash ?
Hi,
Which way is the preferred way you use in doing arithmetic in bash, among expr, $(()) and let ? I need to do a series of arithmetic with the number with zero padding, like 006767. I use $(()) and let, they doesn't seem to recognize well the zero padding number. However expr do a good job here. Here is the output: Code:
[11:48:43 sylye@pc0043 ~]$ echo `expr 006767 + 9 ` |
Alternatively, you can use awk program for calculations, as follow:
echo | awk '{ print <arithmatic operation> }' For instance: echo | awk '{ print 100-100*5/10 }' would result in: 50 |
Leading zeros can be tricky; some tools assume this means an octal num.
As per your experiments, 'expr' ignores leading zeroes, 'let' assumes octal; not sure why (()) comes up with that answer... probably something similar. The technical downside of expr is that its a separate tool, therefore another process being invoked, so a bit more overhead on your system. Another tool is bc http://linux.die.net/man/1/bc Code:
echo "0067 + 9"|bc |
Really it depends on what you are doing and what you can assume is on the system.
older bash's or scripts that may run under bourne shell can not use $(()). expr and $(()) is limited to integers only. awk can do math using floats and is not very big by todays standards, and can handle columns of data (text tables) perl has access to basically the full math library and can process any sort of data, or even network connections and full databases. It also has even better data storage bc on the otherhand can handle ANY sized number or any scale (number of decimal places) I have used it with numbers that has over a thousand digits. Really it is just what your needs and what limitations you have. Actually there are other solutions too. I have image processing scripts using ImageMagick. As I have to have the "convert" command on the system for the script to work, I often use that as I can't be as equally sure bc, awk, or perl, is available for math processing (such as under cgiwin). Its a odd way of doing it but it removes added script dependancies. |
Quote:
You're correct. It seems both let and $(()) think '006767' is octal, which equal to 3575 in decimal, and 0067 as 55. I mistakenly made a typo in my experiment above, so the correct one should be: Code:
[14:24:49 sylye@pc0043 ~]$ let "NEWNO = 006767 + 9"; echo $NEWNO However, if we are to use let and $(()), how to make them think '006767' as decimal ? |
An interesting qn, here's a few things I found on the net
Code:
tlq=$(echo $t | sed 's/0*//') Code:
printf "%d\n" 00005 I've got a feeling you should be able to use bash param fn http://tldp.org/LDP/abs/html/paramet...stitution.html, but I can't find a general soln ie any num of leading zeros, so far... I'm sure someone else will |
hi chrism01,
I found the answer in another place and as well as in the link you have posted :) Just put 'base#your_number' to tell the bash what base we are actually using, then let and $(()) will know how to do their job: Code:
[16:43:22 sylye@pc0043 ~]$ echo $(( 10#006767 + 9 )) shell script is really so cool ! Thanks for A.Thyssen as well for the ideas :) |
Yeah, but I was thinking a bash param trick was possible and would be more elegant ;)
Actually, Manfred Schwarb's soln there is pretty slick, inc a fail safe for a value that only contains zero. |
Quote:
The sed should be sed 's/^00*//' the extra zero is not really needed but it is more exact. |
Quote:
|
I have got one solution and it's working perfectly in all environments, and gives result in desired format:
#!/bin/bash var1=1111688 var2=374335 echo | awk "BEGIN{print 100 - $var2*100/$var1}" Output: 66.3273 For more details please go though: http://www.linuxquestions.org/questi...wk-4175432706/ |
All times are GMT -5. The time now is 10:41 AM. |