3

I have a case like this:

string1="some_string"
string2="some_string"
int1="0.87"
int2="${var}"

$var is the output of some other script, and it has the form 0.994343123 or 0.3454657 or whatever (starts with 0. and the biggest value is around 0.9972343)

Now, I don't know how bash works, but usually string 0.87 is never less than or equal to 0.9999999, they are just different.

I would need something like this (pseudocode):

if (string1 equals string2 and int1 is less than int2):
    do something;
else
    do something else.

What i would expect is 0.87687 is greater than 0.87 (correct?? i was never good at math...)

Can anyone help me with the code for that if??

Thanks in advance!

5
  • 1
    0.87 is actually smaller than 0.876454. 0.87 - 0.876 < 0. In bash you can use the -gt or -lt to compare your variables. Commented Nov 16, 2017 at 14:42
  • 1
    if all the numbers are between 0 and 1, string ordering will work as numerical ordering. Commented Nov 16, 2017 at 14:44
  • @JoachimHuet oh man, sorry, yea, i've just seen the stupidity of what i've written : Commented Nov 16, 2017 at 14:45
  • @karakfa yea, sorry, i want to say that 0,876 is greater than 0,87 Commented Nov 16, 2017 at 14:46
  • naming variable in wrong type is a bad habit. If they are not ints, don't name them so. Commented Nov 16, 2017 at 14:57

3 Answers 3

5

Since bash does not handle floating point arithmetic, you may use bc -l to compare 2 floating point numbers and join the condition with && as:

if [[ $string1 = $string2 && $(bc -l <<< "$int1 < $int2") -eq 1 ]]; then
   echo "yes"
else
   echo "no"
fi
Sign up to request clarification or add additional context in comments.

7 Comments

Can you please explain what $(bc -l <<< "$int1 < $int2") -eq 1 means? And also why you put [[ ]] instead of just [ ]? Thanks!
If you are using bash then prefer [[ ... ]] instead of old [ ... ] because [ runs a separate process but [[ ... ]] is bash internal construct. bc -l <<< "$int1 < $int2" runs math expression "$int1 < $int2" using bc -l command where -l is for handling floating point numbers.
Essentially <<< is the herestring construct. (related to heredoc) and it is only available in bash. It provides the equivalent of echo "$int1 < $int2" | bc -l without requiring the additional subshell for the pipe.
It is the math equivalent equal to operator. For a comparison, bc returns either 1 (true) or 0 (false) so $(bc -l <<< "$int1 < $int2") -eq 1 tests whether the result of $(bc -l <<< "$int1 < $in2") is (true).
Learning all of bash (and the nuances of shell scripting) is kind of like "getting to the end of the internet". The more you learn, the more you learn you have to learn... If you are doing anything Linux (or Unix or mac) then learning bash (the difference between it and POSIX shells, like Bourne shell, ash, and dash) as well as the utilities (find, grep, sed, awk, etc...) is time well spent. Good luck on day 6.
|
2

If the values are between 0 and 1, string comparison will work

s1=..; s2=..
v1="0.876"; v2="0.87"
[[ $s1 = $s2 && $v1 > $v2 ]] && echo yes || echo no 

4 Comments

Chuckling, but yes, a lexigraphic sort works too. (and not just for values between 0 and 1)
Doesn't work... somehow messes with the rest of my script, and outputs everything as Failed instead of Passed.
I'm sure there are some limitations, but understand the > is a bash string comparison operator where "True if string1 sorts after string2 lexicographically.". Essentially testing that 876 sorts after 87 (which it does) Like abc sorts after ab.
equivalent only the numbers are normalized (left zero padded for integers for example) or here as all are less than one. In general it doesn't work since "11' < "2"
1
a=0.86
b=0.865
if ((`echo $a '<' $b|bc`)); then echo 'a<b'; fi

(You can replace the last line by

if (($(echo $a '<' $b|bc))); then echo 'a<b'; fi

but imho it is less readable)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.