## Sunday, February 22, 2009

### Bash function to compare multiple numbers equality

Initially I just made a simple function this way:
`_isEqual () {   local f1=\$1   local f2=\$2   [ \$f1 -eq \$f2 ] && echo "OK" || echo "Not"}`

Which basically check for equality of two numbers.

Then I thought of making it a function which can accept more than two arguments (numbers, float or integer) and check if all are equal.
The idea is to assign the list of numbers to a bash array, and then comparing each number (other than first one) with the first number (1st element in the array).
If they are equal then setting a variable (here k) to 1 else to 0 and performing this operation for all the elements on the array. At the end, if the value of the variable is 1, it means all the numbers are equal else not.
`_isEqual () {arr=("\$@")first=\${arr}len=\${#arr[*]}i=0k=0while [ \$i -lt \$len ]   do      val=\$(echo "\${arr[\$i]}")      #[ \$val -eq \$first ] && k=1 || k=0      #Support to compare float values as well      [ \$(echo \$val == \$first|bc) -eq 1 ] && k=1 || k=0      let i++   done[ \$k -eq 1 ] && echo "All equal" || echo "NOT"}#Some of the calls of the function _isEqual_isEqual 2.3 4_isEqual 90 90 90_isEqual 2.34 2.34 2.34 2.34`

Related post:
- Float comparison in bash script using bc and array
- Bash array introduction and examples

Unknown said...

Lately I realized this solution will fail to check equality of numbers in following case:

_isEqual 2 4
will output "NOT"

But
_isEqual 2 4 2
will output "All equal"

which is wrong.

Any suggestion ? Thanks in advance.

DB Wrangler said...

Thanks for the post, it was just what I was looking for. To answer your question, I think your problem is that you do not quit the loop on finding a non-match - so you are only really checking the first and last array elements.

pipi said...

Thanks i needed something like this to built another function, it helps.
I do agree with QuirkyOracle, à break instead of the \$k assignation is quicker and bullet proof :

[ \$(echo \$val == \$first|bc) -eq 1 ] || break

Thank you.

Unknown said...

@QuirkyOracle @pipi thanks a lot.