比较 shell 脚本中的两个版本号

问题描述 投票:0回答:4

我有一个文件

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
bash shell awk sed grep
4个回答
5
投票

你可以试试

if [ $(echo "${CurrV}\n${ExpecV}"|sort|head -1) != "${CurrV}" ]; then ...

4
投票

如果您使用的是 Debian 系统,那么使用

dpkg
是最简单的:

if dpkg --compare-versions $A lt $B
then
  # $A < $B was true
fi

它支持所有六个比较运算符(请参阅

man dpkg
并在
compare-versions
上搜索)。

一个潜在的缺点:您的版本必须与 Debian 兼容。


2
投票

问题说

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
中,用换行符分隔,然后将未排序的序列与排序的序列进行比较。


1
投票

@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
© www.soinside.com 2019 - 2024. All rights reserved.