是否有办法在bash上比较这些字符串,例如:2.4.5和2.8和2.4.5.1?
当前回答
你可以递归地拆分。和下面的算法进行比较,从这里开始。如果版本相同则返回10,如果版本1大于版本2则返回11,否则返回9。
#!/bin/bash
do_version_check() {
[ "$1" == "$2" ] && return 10
ver1front=`echo $1 | cut -d "." -f -1`
ver1back=`echo $1 | cut -d "." -f 2-`
ver2front=`echo $2 | cut -d "." -f -1`
ver2back=`echo $2 | cut -d "." -f 2-`
if [ "$ver1front" != "$1" ] || [ "$ver2front" != "$2" ]; then
[ "$ver1front" -gt "$ver2front" ] && return 11
[ "$ver1front" -lt "$ver2front" ] && return 9
[ "$ver1front" == "$1" ] || [ -z "$ver1back" ] && ver1back=0
[ "$ver2front" == "$2" ] || [ -z "$ver2back" ] && ver2back=0
do_version_check "$ver1back" "$ver2back"
return $?
else
[ "$1" -gt "$2" ] && return 11 || return 9
fi
}
do_version_check "$1" "$2"
源
其他回答
另一种方法(@joynes的修改版本)比较问题中问到的虚线版本 (即“1.2”、“2.3.4”、“1.0”、“1.10.1”等)。 最大数量的位置必须事先知道。该方法期望最多3个版本位置。
expr $(printf "$1\n$2" | sort -t '.' -k 1,1 -k 2,2 -k 3,3 -g | sed -n 2p) != $2
使用示例:
expr $(printf "1.10.1\n1.7" | sort -t '.' -k 1,1 -k 2,2 -k 3,3 -g | sed -n 2p) != "1.7"
返回:1,因为1.10.1大于1.7
expr $(printf "1.10.1\n1.11" | sort -t '.' -k 1,1 -k 2,2 -k 3,3 -g | sed -n 2p) != "1.11"
返回:0,因为1.10.1比1.11低
### the answer is does we second argument is higher
function _ver_higher {
ver=`echo -ne "$1\n$2" |sort -Vr |head -n1`
if [ "$2" == "$1" ]; then
return 1
elif [ "$2" == "$ver" ]; then
return 0
else
return 1
fi
}
if _ver_higher $1 $2; then
echo higher
else
echo same or less
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
这里是另一个没有任何外部调用的纯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
function version { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; }
这样用:
if [ $(version $VAR) -ge $(version "6.2.0") ]; then
echo "Version is up to date"
fi
(来自https://apple.stackexchange.com/a/123408/11374)
推荐文章
- 检查bash变量是否等于0
- 只使用md5sum获取哈希值(没有文件名)
- 如何生成一个核心转储在Linux上的分段错误?
- 在Bash中测试非零长度字符串:[-n "$var"]或["$var"]
- 如何删除超过X小时的文件
- 如何创建Bash别名?
- 将所有变量从一个shell脚本传递到另一个?
- 如何删除shell脚本中文件名的扩展名?
- 使用xargs调用shell函数
- 如何限制从grep返回的结果的数量?
- 'find -exec'是Linux中的shell函数
- 将值从管道读入shell变量
- 在Bash中重用上一个命令的输出
- RE错误:在Mac OS X上的非法字节序列
- 对bash脚本函数中定义的变量使用curl POST