Bash string comparison

I am trying to compare two lines in a bash script and I am getting very strange results.

if [[ "010" < "01." ]]; then echo "Wrong"; else echo "OK"; fi if [[ "010" < "01.0" ]]; then echo "Wrong"; else echo "OK"; fi if [ "010" \< "01." ]; then echo "Wrong"; else echo "OK"; fi if [ "010" \< "01.0" ]; then echo "Wrong"; else echo "OK"; fi 

Having read the documentation, it seemed that [[ < ]] and [ \< ] should work the same, but they do not. It seems that [[ < ]] does not work correctly when strings do not have the same length. Did I miss something?

Edit: Expected Result: 4 x OK . Tested:

  • CentOS Version 6.4 (Final) - GNU bash, Version 4.1.2 (1) -release (x86_64-redhat-linux-gnu) ( OK Wrong OK OK )
  • Ubuntu 14.04.2 LTS - GNU bash version 4.3.11 (1) -release (x86_64-pc-linux-gnu) ( OK Wrong OK OK )
  • openSUSE 13.1 (Bottle) (x86_64) - GNU bash version 4.2.53 (1) -release (x86_64-suse-linux-gnu) ( OK OK OK OK )
+7
string comparison bash
source share
3 answers

Here is the documentation from the help test :

STRING1> STRING2

True if STRING1 sorts after STRING2 lexicographically.

Take your first if as an example:

 if [[ "010" < "01." ]]; then echo "Wrong"; else echo "OK"; fi 

In Bash, the string is "01." sorts lexicographically before the line "010" (you can test other tools, such as Microsoft Excel), so the comparison returns false. This applies to all 4 of your comparisons.

Note that adding an extra 0 to the end of "01." does not change the order compared to "010" , so you still get the same result.

+1
source share

The reason may be that, starting with bash 4.1, and> string comparison operators correspond to the language.

So, between the two systems you can have the following differences:

  • different locales - check by running locale (to determine the various settings for the locale, see https://unix.stackexchange.com/a/87763/122478 )
  • even if the locales are the same, storet compat31 or compat32 (bash 3.1 or 3.2 compatibility mode) can be enabled, which means that string comparisons will not respect the locale - check by running shopt

Further reading:

0
source share

If you want to compare an integer, you should do this:

if [[10 <1]]; then the echo "10 <1", otherwise the echo "10> 1"; fi 10> 1

If you want to compare float, you should look at this topic: How to compare float in Bash?

In your example:

echo "10 <1.0" | bc return: 0

echo "10> 1.0" | bc retunr: 1

-one
source share

All Articles