在bash中排序无法正常工作

时间:2018-07-14 03:24:38

标签: bash shell awk sed grep

我有一个变量VarExp,具有以下2个值

1.5.2
1.5.3

我还有另一个变量VarCurr,其后跟1个值

1.8.1

我想将VarCurrVarExp进行比较,并且仅在

时才想echo SUCCESS
VarCurr >= VarExp

我编写了以下代码,但是它始终返回FAILURE

VarExp='1.5.2 1.5.3'
VarCurr='1.8.1'

printf -v versions '%s\n%s' "$VarExp" "$VarCurr"
if [[ $versions = "$(sort -V <<< "$versions")" ]]; then
    echo 'FAILURE'
else
    echo 'SUCCESS'
fi

VarCurr必须> = VarExp中包含的最小值

4 个答案:

答案 0 :(得分:4)

我建议使用一种语言,该语言可以正确地对版本对象进行对象化处理,并且可以理解major.minor.build.revision。这是一个bash脚本示例,该脚本从Perl借来进行版本解析:

#!/bin/bash

VarExp='1.5.2 1.5.3'
VarCurr='1.8.1'

for i in $VarExp; do {
    perl -e 'use version;exit !(version->parse('$VarCurr') >= version->parse('$i'));' && {
        echo 'SUCCESS'
        exit
    }
}; done

echo 'FAILURE'
exit

当然,仅用Perl编写整个内容会更为优美。

编辑:这是另一个使用Python的示例:

#!/bin/bash

VarExp='1.5.3 1.5.6'
VarCurr='1.5.3'

for i in $VarExp; do {
    python -c 'from distutils.version import LooseVersion;\
    exit(LooseVersion("'$VarCurr'") >= LooseVersion("'$i'"))' || {
        echo 'SUCCESS'
        exit
    }
}; done

echo 'FAILURE'
exit

答案 1 :(得分:3)

如果您正在使用bash,则可以使用数组。它们使处理列表变得更加容易和安全。另外,由于您不能依靠sort -V之类的功能来实现可移植性,因此一种选择可能是将您的数字转换为可以更好地进行bash比较的数字。以下假设您的字符串中的任何数字都不会大于3位数字。加盐调味。

#!/bin/bash

VarExp='1.5.2 1.5.3'
VarCurr='1.8.1'

a=( $VarExp )

function padsemver {
    local IFS=.
    local -a a=()
    read -a a <<<"$1"
    printf '%03d' "${a[@]}"
}

x="$(padsemver "$VarCurr")"

for i in "${a[@]}"; do
    if [[ 10#"$x" -gt 10#"$(padsemver $i)" ]]; then
        printf '%s\n' "SUCCESS"
        exit 0
    fi
done

printf '%s\n' "FAILURE"
exit 1

这使用padsemver()函数将1.5.3转换为001005003,从而使其与test[[中的数字比较兼容。 (10#确保以0开头的数字将被解释为十进制而不是八进制。)

如果您需要的话,您当然可以将整个测试放到自己的函数中,而不是独立的脚本中。

答案 2 :(得分:3)

使用GNU对-V进行排序:

$ cat tst.sh
#!/bin/bash
varExp='1.5.2 1.5.3'
varCurr=$1

minVarExp=$(printf '%s\n' $varExp | sort -V | head -1)
maxOfVers=$(printf '%s\n' "$minVarExp" "$varCurr" | sort -V | tail -1)

if [[ $maxOfVers = $varCurr ]]; then
    echo 'SUCCESS'
else
    echo 'FAILURE'
fi

$ ./tst.sh 1.8.1
SUCCESS

$ ./tst.sh 1.5.1
FAILURE

$ ./tst.sh 1.5.2
SUCCESS

答案 3 :(得分:2)

能否请您尝试以下操作,如果有帮助,请告诉我。

varExp="1.5.2
1.5.4"
VarCurr="1.8.1"
echo "$varExp" |
awk -v current="$VarCurr" '{
  curr=current
  value=$0
  gsub(/\./,"",curr)
  gsub(/\./,"",value)
  if(curr>=value){
    print "SUCCESS, value of varExp " current " is more than variable varExp " $0"."
  }
}'

输出如下。

SUCCESS, value of varExp 1.8.1 is more than variable varExp 1.5.2.
SUCCESS, value of varExp 1.8.1 is more than variable varExp 1.5.4.

假设您名为varExp的变量在新行中具有数值,那么通过将其值包装在"中将使新行保持活动状态。