簡體   English   中英

排序在bash中無法正常工作

[英]Sorting not working correctly in bash

我有一個變量VarExp其中包含2個值

1.5.2
1.5.3

我有另一個變量VarCurr ,其值為1

1.8.1

我想將VarCurrVarExp進行比較,並希望僅在VarExp 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包含的最低值

我建議使用一種能夠正確地客觀化版本對象的語言,並且可以理解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

如果您正在使用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開頭的數字將被解釋為十進制而不是八進制。)

你當然可以將整個測試放入自己的功能而不是一個獨立的腳本,如果這是你需要的。

使用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

你可以嘗試一下,讓我知道這是否對你有幫助。

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的變量在新行中具有數值,因此通過將其值包裝在"將使新行保持活動狀態。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM