Comparing numbers in Bash

前端 未结 8 1718
栀梦
栀梦 2020-11-22 02:03

I\'m starting to learn about writing scripts for the bash terminal, but I can\'t work out how to get the comparisons to work properly. The script I\'m using is:



        
相关标签:
8条回答
  • 2020-11-22 02:36

    This code can also compare floats. It is using awk (it is not pure bash), however this shouldn't be a problem, as awk is a standard POSIX command that is most likely shipped by default with your operating system.

    $ awk 'BEGIN {return_code=(-1.2345 == -1.2345) ? 0 : 1; exit} END {exit return_code}'
    $ echo $?
    0
    $ awk 'BEGIN {return_code=(-1.2345 >= -1.2345) ? 0 : 1; exit} END {exit return_code}'
    $ echo $?
    0
    $ awk 'BEGIN {return_code=(-1.2345 < -1.2345) ? 0 : 1; exit} END {exit return_code}'
    $ echo $?
    1
    $ awk 'BEGIN {return_code=(-1.2345 < 2) ? 0 : 1; exit} END {exit return_code}'
    $ echo $?
    0
    $ awk 'BEGIN {return_code=(-1.2345 > 2) ? 0 : 1; exit} END {exit return_code}'
    $ echo $?
    

    To make it shorter for use, use this function:

    compare_nums()
    {
       # Function to compare two numbers (float or integers) by using awk.
       # The function will not print anything, but it will return 0 (if the comparison is true) or 1
       # (if the comparison is false) exit codes, so it can be used directly in shell one liners.
       #############
       ### Usage ###
       ### Note that you have to enclose the comparison operator in quotes.
       #############
       # compare_nums 1 ">" 2 # returns false
       # compare_nums 1.23 "<=" 2 # returns true
       # compare_nums -1.238 "<=" -2 # returns false
       #############################################
       num1=$1
       op=$2
       num2=$3
       E_BADARGS=65
    
       # Make sure that the provided numbers are actually numbers.
       if ! [[ $num1 =~ ^-?[0-9]+([.][0-9]+)?$ ]]; then >&2 echo "$num1 is not a number"; return $E_BADARGS; fi
       if ! [[ $num2 =~ ^-?[0-9]+([.][0-9]+)?$ ]]; then >&2 echo "$num2 is not a number"; return $E_BADARGS; fi
    
       # If you want to print the exit code as well (instead of only returning it), uncomment
       # the awk line below and comment the uncommented one which is two lines below.
       #awk 'BEGIN {print return_code=('$num1' '$op' '$num2') ? 0 : 1; exit} END {exit return_code}'
       awk 'BEGIN {return_code=('$num1' '$op' '$num2') ? 0 : 1; exit} END {exit return_code}'
       return_code=$?
       return $return_code
    }
    
    $ compare_nums -1.2345 ">=" -1.2345 && echo true || echo false
    true
    $ compare_nums -1.2345 ">=" 23 && echo true || echo false
    false
    
    0 讨论(0)
  • 2020-11-22 02:40

    The bracket stuff (e.g., [[ $a -gt $b ]] or (( $a > $b )) ) isn't enough if you want to use float numbers as well; it would report a syntax error. If you want to compare float numbers or float number to integer, you can use (( $(bc <<< "...") )).

    For example,

    a=2.00
    b=1
    
    if (( $(bc <<<"$a > $b") )); then 
        echo "a is greater than b"
    else
        echo "a is not greater than b"
    fi
    

    You can include more than one comparison in the if statement. For example,

    a=2.
    b=1
    c=1.0000
    
    if (( $(bc <<<"$b == $c && $b < $a") )); then 
        echo "b is equal to c but less than a"
    else
        echo "b is either not equal to c and/or not less than a"
    fi
    

    That's helpful if you want to check if a numeric variable (integer or not) is within a numeric range.

    0 讨论(0)
  • 2020-11-22 02:42

    Plain and simple

    #!/bin/bash
    
    a=2462620
    b=2462620
    
    if [ "$a" -eq "$b" ];then
      echo "They're equal";
    fi
    

    You can check out this cheatsheet if you want more number comparsions in the wonderful world of Bash Scripting.

    Shortly, integers can only be compared with:

    -eq # equal
    -ne # not equal
    -lt # less than
    -le # less than or equal
    -gt # greater than
    -ge # greater than or equal
    
    0 讨论(0)
  • 2020-11-22 02:51

    In Bash I prefer doing this as it addresses itself more as a conditional operation unlike using (( )) which is more of arithmetic.

    [[ N -gt M ]]
    

    Unless I do complex stuffs like

    (( (N + 1) > M ))
    

    But everyone just has their own preferences. Sad thing is that some people impose their unofficial standards.

    Update:

    You actually can also do this:

    [[ 'N + 1' -gt M ]]
    

    Which allows you to add something else which you could do with [[ ]] besides arithmetic stuff.

    0 讨论(0)
  • 2020-11-22 02:52

    In bash, you should do your check in arithmetic context:

    if (( a > b )); then
        ...
    fi
    

    For POSIX shells that don't support (()), you can use -lt and -gt.

    if [ "$a" -gt "$b" ]; then
        ...
    fi
    

    You can get a full list of comparison operators with help test or man test.

    0 讨论(0)
  • 2020-11-22 02:52

    If you have floats you can write a function and then use that e.g.

    #!/bin/bash
    
    function float_gt() {
        perl -e "{if($1>$2){print 1} else {print 0}}"
    }
    
    x=3.14
    y=5.20
    if [ $(float_gt $x $y) == 1 ] ; then
        echo "do stuff with x"
    else
        echo "do stuff with y"
    fi
    
    0 讨论(0)
提交回复
热议问题