6

In shell script how can we compare (integer and floating point) ,(flaoting point and floating point),(floating point and integer),(integer and integer) with only one if condition.

i have few examples like

 set X=3.1
  set Y=4.1
  if [ $X < $Y ] then
    echo "wassup"
  endif

But running the above from cron job doesnt seem to work.

1

4 Answers 4

21

The way to carry out floating point operations in bash is to use bc which is available on almost all linux distributions.

# bc will return 0 for false and 1 for true
if [ $(echo "23.3 > 7.3" | bc) -ne 0 ] 
then 
  echo "wassup"
fi

There's a good article available on linux journal about floating point math in bash using bc.

Sign up to request clarification or add additional context in comments.

3 Comments

i tried the following and got a error as unary operated expected
interesting. I have it working fine here. Hmmm. What your error means (I think) is that the $(echo "$a > $b" | bc) did not return a value. Can you try the subshell on its own?
IE: Your variables are not properly assigned to. echo $X will be an empty line, for example.
1

Bah itself only handles integers. Use bc:

echo "$X>$Y" | bc 
0
echo "$X<$Y" | bc 
1

You don't need to worry about scale. It is just for the preocision of output formats:

X=3.000001
Y=3.0001
echo "$X>$Y" | bc 
0
echo "$X<$Y" | bc 
1
echo "scale=1;$X<$Y" | bc 
1

Comments

0

below example works on bash shell.

 X=3.1
 Y=4.1
 if [ $X -le $Y ]
 then
    echo "wassup"
 fi

you may want to learn shell script here

2 Comments

This doesn't work here, as bash doesn't deal with floating points: $ test "34.4" -gt "5.4" -> bash: test: 34.4: integer expression expected
I do not doubt your sincerity :) I'm just saying that this isn't guaranteed to work on Linux bash --version gives me GNU bash, version 4.2.8(1)-release (x86_64-pc-linux-gnu)
0

EDIT. based on the comments to this answer (thanks to user unknown and glenn jackman), it seems that when using bc for a true/false test, the required bash test is simply:

  • (( $(echo "$X < $Y" |bc) )) ... see the test results and script below

wheras, the comparison to -ne 0 is needed for the old style bash [ ] test.


bash does not natively handle floating point numbers, but you can call a utility such as bc

From man bc - An arbitrary precision calculator language

X=3.1
Y=4.1
# This test has two superfluous components. 
# See EDIT (above) and TESTS below
if (($(echo "scale=9; $X < $Y" |bc)!=0)) ;then
    echo "wassup"
fi

TEST results:

if [  "1"  ]   true
   [  "1"  ]   true
if [  "0"  ]   true
   [  "0"  ]   true

if [   1   ]   true
   [   1   ]   true
if [   0   ]   true
   [   0   ]   true

if (( "1" ))   true
   (( "1" ))   true
if (( "0" ))   false
   (( "0" ))   false

if ((  1  ))   true
   ((  1  ))   true
if ((  0  ))   false
   ((  0  ))   false

echo "1<1"|bc  true
echo "1<0"|bc  true

TEST script:

printf 'if [  "1"  ]   '; if [ "1" ]; then echo true; else echo false; fi
printf '   [  "1"  ]   ';    [ "1" ]  &&   echo true  ||   echo false
printf 'if [  "0"  ]   '; if [ "0" ]; then echo true; else echo false; fi
printf '   [  "0"  ]   ';    [ "0" ]  &&   echo true  ||   echo false
echo  
printf 'if [   1   ]   '; if [  1  ]; then echo true; else echo false; fi
printf '   [   1   ]   ';    [  1  ]  &&   echo true  ||   echo false
printf 'if [   0   ]   '; if [  0  ]; then echo true; else echo false; fi
printf '   [   0   ]   ';    [  0  ]  &&   echo true  ||   echo false
echo  
printf 'if (( "1" ))   '; if (("1")); then echo true; else echo false; fi
printf '   (( "1" ))   ';    (("1"))  &&   echo true  ||   echo false
printf 'if (( "0" ))   '; if (("0")); then echo true; else echo false; fi
printf '   (( "0" ))   ';    (("0"))  &&   echo true  ||   echo false
echo  
printf 'if ((  1  ))   '; if (( 1 )); then echo true; else echo false; fi
printf '   ((  1  ))   ';    (( 1 ))  &&   echo true  ||   echo false
printf 'if ((  0  ))   '; if (( 0 )); then echo true; else echo false; fi
printf '   ((  0  ))   ';    (( 0 ))  &&   echo true  ||   echo false
echo
printf 'echo "1<1"|bc  '; echo "1<1"|bc >/dev/null  && echo true || echo false 
printf 'echo "1<0"|bc  '; echo "1<0"|bc >/dev/null  && echo true || echo false 

5 Comments

scale is superfluous, if you just want to test for true and false. !=0 is superfluous too - that's what's done already.
The !=0 is not superfluous: bc prints 0 or 1 for false or true. In both cases, the exit status is zero. So, you must compare the command output to something.
Nice idea, but wrong: if (($(echo "$X > $Y" | bc))) ; then echo wassup; else echo pussaw; fi. Reason: $(...) captures the output. ((...)) evaluates.
It seems you are both right, for different formats :) ... I've added tests to my answer.
@glennjackman: I forgot the notification mark for you. Sorry.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.