如何比较Shell脚本中的十进制值,例如12.2.0.13至12.2.0.14

时间:2019-03-22 03:15:20

标签: shell

我需要将值与4个小数点进行比较。我尝试了bc,但是没有用。我该怎么办?

amt="12.2.0.13" opn_amt="12.2.0.14"
if [ $(bc <<< "$amt <= $opn_amt") -eq 1 ]; then
  echo "12.2.0.13"
else
  echo "12.2.0.14" 
fi

3 个答案:

答案 0 :(得分:0)

如果两个字符串中每个.之间的位数固定且相同,则可以通过从变量中删除.进行比较。因此在比较之前,它们将被视为integer

sh-4.4$ amt="12.2.0.13"                                                                                                          
sh-4.4$ open_amt="12.2.0.14"                                                                                                     
sh-4.4$ [ "${amt//./}" -gt "${open_amt//./}" ] && echo "$amt" || echo "$open_amt"                                                
12.2.0.14  
sh-4.4$ 

答案 1 :(得分:0)

请尝试以下代码;

要输出更大的IP:

amt="12.2.0.13";opn_amt="12.1.0.14";C=$opn_amt; for v in 1 2 3 4; do A=$(echo $amt | cut -d '.' -f$v); B=$(echo $opn_amt | cut -d '.' -f$v); if [ $A -gt $B ]; then C=$amt; break; fi; done; echo $C

要输出较少的IP:

amt="12.1.0.13";opn_amt="12.1.0.14";C=$opn_amt; for v in 1 2 3 4; do A=$(echo $amt | cut -d '.' -f$v); B=$(echo $opn_amt | cut -d '.' -f$v); if [ $A -lt $B ]; then C=$amt; break; fi; done; echo $C

要基于条件做某事:

$ amt="12.2.0.14";opn_amt="12.1.0.14";C=0; for v in 1 2 3 4; do A=$(echo $amt | cut -d '.' -f$v); B=$(echo $opn_amt | cut -d '.' -f$v);if [ $A -lt $B ]; then C=1; break; fi; done
$ if [ $C -eq 0 ]
> then
> echo "amt is great or equal then opn_amt"
> else
> echo "amt is less than opn_amt"
> fi
amt is great or equal then opn_amt

答案 2 :(得分:0)

这是ksh的比较器实现。使其适合其他外壳作为练习供读者使用。

function get_version_component {
    typeset -r version="$1"
    typeset -ri index="$2"
    typeset value=$(print -- "$version" | cut -d. -f$index -s)
    [[ "$value" == "" ]] && value=0
    [[ "$value" == +([0-9]) ]] || return 1
    print $value
    return 0
}

# Compare two version numbers, up to 20 levels deep.
# For comparison purposes, missing values are assumed to be zero (1.2.3.0 == 1.2.3).
# Output -1 on first < second, 0 if they are equal, 1 if first > second.
# (($(compare_versions 10.3.59.37 10.3.59) > 0)) && echo pass1
# Returns 0 on success, non-0 on invalid version number.
function compare_versions {
    [[ -z "$1" || -z "$2" ]] && return 1
    typeset -r first="${1}.0" second="${2}.0"
    typeset -i index=0 n1 n2
    for (( index = 1 ; index < 20 ; index++ ))
    do
        n1=$(get_version_component "$first" $index) || return 1
        n2=$(get_version_component "$second" $index) || return 1
        if ((n1 < n2))
        then
            print -- "-1"
            return 0
        elif ((n1 > n2))
        then
            print "1"
            return 0
        fi
    done
    print "0"
    return 0
}



# # Test cases
# # Equal
# compare_versions 10.3.59.37 10.3.59.37 || print errored
# compare_versions 10.3.59.0 10.3.59 || print errored
# compare_versions 10.3.59 10.3.59.0 || print errored
# 
# # Less
# compare_versions 9.2.59.37 10.3.59.37 || print errored
# compare_versions 10.2.59.37 10.3.59.37 || print errored
# compare_versions 10.3.59.37 10.3.59.39 || print errored
# compare_versions 10.3.59.37 10.3.60 || print errored
# compare_versions 10.3.59 10.3.59.37 || print errored
# 
# # Greater
# compare_versions 10.2.59.37 9.3.59.37 || print errored
# compare_versions 10.3.59.37 10.2.59.37 || print errored
# compare_versions 10.3.59.39 10.3.59.37 || print errored
# compare_versions 10.3.60 10.3.59.37 || print errored
# compare_versions 10.3.59.37 10.3.59 || print errored
# 
# # Errors
# compare_versions 10.x.59.37 10.3.59.37 && print "Error didn't 1"
# compare_versions 10.3.59.37 "" && print "Error didn't 2"
# compare_versions "" 9.3.59.37 && print "Error didn't 3"
#