• VMware

    Learn about VMware virtualization for its products like vsphere ESX and ESXi, vCenter Server, VMware View, VMware P2V and many more

  • Linux

    Step by step configuration tutorials for many of the Linux services like DNS, DHCP, FTP, Samba4 etc including many tips and tricks in Red Hat Linux.

  • Database

    Learn installation and configuration of databases like Oracle, My SQL, Postgresql, etc including many other related tutorials in Linux.

  • How to compare floating point / decimal / version numbers using bash in Linux

    I could not find any single utility in bash which can do such comparison for versions or decimals or floating point numbes unless it is an integer.

    Although if you want to do simple comparison i.e. if two floating/version numbers are equal or un-equal then you have plenty of tools.

    For example "bc" utility but its not 100% reliable for all scenarios although it can be handly if you just want to check if the two numbers are equal or un-equal.

    For example in the below script I have two values
    #!/bin/bash

    num1=2.21
    num2=2.31

    _output=`echo "$num1 != $num2" | bc`
    if [ $_output == "1" ]; then
       echo "$num1 is not equal to $num2"
    else
       echo "$num1 is equal to $num2"
    fi

    If I execute the above script
    # /tmp/compare.sh
    2.21 is not equal to 2.31

    So that was sort of a straight forward case, lets spice it up a little bit with more complex comparison
    #!/bin/bash

    num1=2.21
    num2=2.30

    _output=`echo "$num1 >= $num2" | bc`
    if [ $_output == "1" ]; then
       echo "$num1 is greater than or equal to $num2"
    else
       echo "$num1 is lesser than $num2"
    fi

    If I execute my script, the comparison went just fine
    # /tmp/compare.sh
    2.21 is lesser than 2.30

    But what if I made it more tricky like below
    #!/bin/bash

    num1=2.15
    num2=2.3

    _output=`echo "$num1 >= $num2" | bc`
    if [ $_output == "1" ]; then
       echo "$num1 is greater than or equal to $num2"
    else
       echo "$num1 is lesser than $num2"
    fi

    If I execute the same
    # /tmp/compare.sh
    2.15 is lesser than 2.3

    which is wrong, 2.15 is actually greater than 2.3 so my comparison failed.

    Hence with comparison checks like "less than equal to" or "greater than equal to" then we go out of luck with "bc" utility.


    What if I had some version number, so will "bc" work?

    Let us take the same example as above with different value
    #!/bin/bash

    num1=2.15.4
    num2=2.3.6

    _output=`echo "$num1 >= $num2" | bc`
    if [ $_output == "1" ]; then
       echo "$num1 is greater than or equal to $num2"
    else
       echo "$num1 is lesser than $num2"
    fi

    If I execute the above script I get the below error.
    # /tmp/compare.sh
    (standard_in) 1: syntax error
    (standard_in) 1: syntax error
    /tmp/compare.sh: line 7: [: ==: unary operator expected

    2.15.4 is lesser than 2.3.6

    The one reliable way I use is to convert the version numbers into integer values.
    #!/bin/bash

    function convert_to_integer {
     echo "$@" | awk -F "." '{ printf("%03d%03d%03d\n", $1,$2,$3); }';
    }

    num1=2.15.4
    num2=2.3.6


    if [ "$(convert_to_integer $num1)" -gt "$(convert_to_integer $num2)" ];then
       echo "$num1 is greater than or equal to $num2"
    else
       echo "$num1 is lesser than $num2"
    fi

    Let us try to execute the above script
    # /tmp/compare.sh
    2.15.4 is greater than or equal to 2.3.6

    looks like this gives us the perfect comparison

    Lets see what is happening in the backend
    # sh -x /tmp/compare.sh
    + num1=2.15.4
    + num2=2.3.6
    ++ convert_to_integer 2.15.4
    ++ echo 2.15.4
    ++ awk -F . '{ printf("%03d%03d%03d\n", $1,$2,$3); }'
    ++ convert_to_integer 2.3.6
    ++ echo 2.3.6
    ++ awk -F . '{ printf("%03d%03d%03d\n", $1,$2,$3); }'
    + '[' 002015004 -gt 002003006 ']'
    + echo '2.15.4 is greater than or equal to 2.3.6'
    2.15.4 is greater than or equal to 2.3.6

    Here I am removing the decimal and adding "000" to make the comparison happen between integers.
    You can tweak the script depending upon your requirement

    Suppose you want to compare some rpm version from a Linux node

    In the below script I will compare "bash" rpm version
    #!/bin/bash

    function convert_to_integer {
     
    echo "$@" | awk -F "." '{ printf("%03d%03d%03d%03d%03d\n", $1,$2,$3,$4,$5); }';
    }

    num1=`rpm -q bash | awk -F "-" '{print $2"."$3}'`
    # Make sure bash rpm version is equal to or greater than "3.2-147.30.1"
    num2=3.2-147.30.1
    # Split and join the version numbers with "." instead of "-"
    num2=`echo $num2 | sed -e 's/-/./g'`

    if [ "$(convert_to_integer $num1)" -ge "$(convert_to_integer $num2)" ];then
       echo "$num1 is greater than or equal to $num2"
    else
       echo "$num1 is lesser than $num2"
    fi

    Lets execute our script
    # sh -x /tmp/compare.sh
    ++ rpm -q bash
    ++ awk -F - '{print $2"."$3}'
    + num1=3.2.147.35.1
    + num2=3.2-147.30.1
    ++ echo 3.2-147.30.1
    ++ sed -e s/-/./g
    + num2=3.2.147.30.1
    ++ convert_to_integer 3.2.147.35.1
    ++ awk -F . '{ printf("%03d%03d%03d%03d%03d\n", $1,$2,$3,$4,$5); }'
    ++ echo 3.2.147.35.1
    ++ convert_to_integer 3.2.147.30.1
    ++ echo 3.2.147.30.1
    ++ awk -F . '{ printf("%03d%03d%03d%03d%03d\n", $1,$2,$3,$4,$5); }'
    + '[' 003002147035001 -ge 003002147030001 ']'
    + echo '3.2.147.35.1 is greater than or equal to 3.2.147.30.1'
    3.2.147.35.1 is greater than or equal to 3.2.147.30.1


    Here you have to make sure to increase the printf values to increment the variable count based on the number of values you want to compare in a version. Here for example I incremented the value to "5"

    I would be happy if someone can share more tools or ways to compare such version numbers.

    Follow the below links for more tutorials

    Configure Red Hat Cluster using VMware, Quorum Disk, GFS2, Openfiler
    Tutorial for Monitoring Tools SAR and KSAR with examples in Linux
    How to configure Samba 4 Secondary Domain Controller
    How to secure Apache web server in Linux using password (.htaccess)
    How to register Red Hat Linux with RHN (Red Hat Network )
    Red hat Enterprise Linux 5.5 Installation Guide (Screenshots)
    15 tips to enhance security of your Linux machine
    Why is Linux more secure than windows and any other OS
    What is the difference between "su" and "su -" in Linux?
    What is kernel-PAE in Linux?
    What is swappiness and how do we change its value?
    How to log iptables messages in different log file
    What are the s and k scripts in the etc rcx.d directories
    How to check all the currently running services in Linux
    How to auto start service after reboot in Linux
    What is virtual memory, paging and swap space?


    How to compare floating point / decimal / version numbers using bash in Linux How to compare floating point / decimal / version numbers using bash in Linux Reviewed by Deepak Prasad on Sunday, November 19, 2017 Rating: 5

    No comments:

    Powered by Blogger.