是否有办法在bash上比较这些字符串,例如:2.4.5和2.8和2.4.5.1?


当前回答

这里是另一个没有任何外部调用的纯bash解决方案:

#!/bin/bash

function version_compare {

IFS='.' read -ra ver1 <<< "$1"
IFS='.' read -ra ver2 <<< "$2"

[[ ${#ver1[@]} -gt ${#ver2[@]} ]] && till=${#ver1[@]} || till=${#ver2[@]}

for ((i=0; i<${till}; i++)); do

    local num1; local num2;

    [[ -z ${ver1[i]} ]] && num1=0 || num1=${ver1[i]}
    [[ -z ${ver2[i]} ]] && num2=0 || num2=${ver2[i]}

    if [[ $num1 -gt $num2 ]]; then
        echo ">"; return 0
    elif
       [[ $num1 -lt $num2 ]]; then
        echo "<"; return 0
    fi
done

echo "="; return 0
}

echo "${1} $(version_compare "${1}" "${2}") ${2}"

还有更简单的解决方案,如果你确定所讨论的版本在第一个点后不包含前导零:

#!/bin/bash

function version_compare {

local ver1=${1//.}
local ver2=${2//.}


    if [[ $ver1 -gt $ver2 ]]; then
        echo ">"; return 0
    elif    
       [[ $ver1 -lt $ver2 ]]; then
        echo "<"; return 0
    fi 

echo "="; return 0
}

echo "${1} $(version_compare "${1}" "${2}") ${2}"

这适用于像1.2.3 vs 1.3.1 vs 0.9.7这样的版本,但不适用于其他版本 1.2.3 vs 1.2.3.0或1.01.1 vs 1.1.1

其他回答

这里一个有用的技巧是字符串索引。

$ echo "${BASH_VERSION}"
4.4.23(1)-release

$ echo "${BASH_VERSION:0:1}"
4

您可以通过版本命令行查看版本约束

$ version ">=1.0, <2.0" "1.7"
$ go version | version ">=1.9"

Bash脚本示例:

#!/bin/bash

if `version -b ">=9.0.0" "$(gcc --version)"`; then
  echo "gcc version satisfies constraints >=9.0.0"
else
  echo "gcc version doesn't satisfies constraints >=9.0.0"
fi

可能没有普遍正确的方法来实现这一点。如果您正在尝试比较Debian包系统中的版本,请尝试dpkg——compare-versions <first> <relation> <second>。

我希望这对某些人有用(使用awk)

  #!/bin/bash

  available_version=1.2.3 # or online version
  this_version=1.2.1

  if [[ "ok" == "$(echo | awk "(${available_version} > ${this_version}) { print \"ok\"; }")" ]]; then
    echo "Notice, new version is available"
  elif [[ "ok" == "$(echo | awk "(${available_version} == ${this_version}) { print \"ok\"; }")" ]]; then
    echo "OK, version is up to date"
  else
    echo "Warning, the current version is ahead of the online version!"
  fi

感谢Dennis的解决方案,我们可以扩展它以允许比较运算符'>','<','=','==','<='和'>='。

# compver ver1 '=|==|>|<|>=|<=' ver2
compver() { 
    local op
    vercomp $1 $3
    case $? in
        0) op='=';;
        1) op='>';;
        2) op='<';;
    esac
    [[ $2 == *$op* ]] && return 0 || return 1
}

然后我们可以在表达式中使用比较运算符,比如:

compver 1.7 '<=' 1.8
compver 1.7 '==' 1.7
compver 1.7 '=' 1.7

并且只测试结果的真/假,比如:

if compver $ver1 '>' $ver2; then
    echo "Newer"
fi