我有一个文件
file1
,如下所示,包含当前版本和预期版本号:
CurrV:1.5.2
ExpecV:1.8.1
我想编写一个bash脚本来比较这两个值,如果
ExpecV>=CurrV
那么我应该echo SUCCESS
,否则我应该echo FAILURE
。
到目前为止我已经写了这个东西,但不知道如何继续:
#!/bin/bash
## Code already written to fetch `ExpecV` and `CurrV` from `file1`
echo $ExpecV | grep $CurrV > /dev/null
if [ $? -eq 0 ]
then
echo SUCCESS
else
echo FAILURE
fi
你可以试试
if [ $(echo "${CurrV}\n${ExpecV}"|sort|head -1) != "${CurrV}" ]; then ...
如果您使用的是 Debian 系统,那么使用
dpkg
是最简单的:
if dpkg --compare-versions $A lt $B
then
# $A < $B was true
fi
它支持所有六个比较运算符(请参阅
man dpkg
并在 compare-versions
上搜索)。
一个潜在的缺点:您的版本必须与 Debian 兼容。
问题说
ExpecV>=CurrV
应该被视为成功,但这没有多大意义(当前版本比预期旧,可能会破坏某些内容),并且在您对此答案的评论中,您暗示所需的行为是另一种方式周围,所以这就是这个答案的作用。
这需要对其
-V
选项进行 GNU 排序(版本排序):
if cmp -s <(cut -d: -f2 infile) <(cut -d: -f2 infile | sort -V); then
echo 'FAILURE'
else
echo 'SUCCESS'
fi
这要求带有
CurrV
的行始终是第一行。它使用 cut
提取冒号后面的部分,并将未排序的(第一个进程替换 <(...)
)与版本排序的输出(第二个进程替换)进行比较。
如果相同,即第二行的版本大于或等于第一行的版本,则
cmp
的退出状态为成功,我们打印FAILURE
;如果它们不相同,则意味着 sort
颠倒了顺序,并且预期版本小于当前版本,因此我们打印 SUCCESS
。
-s
标志用于抑制cmp
的输出(“沉默”);我们只对退出状态感兴趣。
如果
1.5.2
和 1.8.1
已经在单独的变量 CurrV
和 ExpecV
中,您可以执行类似的操作,如下所示:
CurrV='1.5.2'
ExpecV='1.8.1'
printf -v versions '%s\n%s' "$CurrV" "$ExpecV"
if [[ $versions = "$(sort -V <<< "$versions")" ]]; then
echo 'FAILURE'
else
echo 'SUCCESS'
fi
这会将两个变量存储到
versions
中,用换行符分隔,然后将未排序的序列与排序的序列进行比较。
@benjamin-w 和@Walter A 的答案都非常简洁。我们还可以使用 for 循环比较子版本的数值,如下所示:
#!/bin/bash
#
# given 2 version numbers:
# check if ExpecV>=CurrV: SUCCESS
#
CurrV=1.5.2
ExpecV=1.8.1
#
# here below:
# xarr: array of split CurrV numerical elements
# yarr: array of split ExpecV numerical elements
# isnewer: key if version ExpecV is newer than or equal to CurrV
#
#
# use parameter expansion to replace dot by space,
# and then convert them to arrays:
#
xarr=(${CurrV//./ })
yarr=(${ExpecV//./ })
#
# suppose that ExpecV is newer (bigger) or equal to CurrV version:
#
isnewer=true
#
# loop over array keys:
#
for i in "${!xarr[@]}"; do
#
#printf '${xarr[%s]}=%s\n' $i ${xarr[i]}
#printf '${yarr[%s]}=%s\n' $i ${yarr[i]}
#
#
# compare sub-version values: break if not equal:
#
if [ ${yarr[i]} -gt ${xarr[i]} ]; then
break
elif [ ${yarr[i]} -lt ${xarr[i]} ]; then
isnewer=false
break
fi
done
#
# show result:
#
if [ $isnewer == true ]; then
echo "SUCCESS: $ExpecV is newer than or equal to $CurrV."
else
echo "FAILURE: $ExpecV is not newer than or equal to $CurrV."
fi