Reputation: 15581
I have a variable VarExp
with following 2 values
1.5.2
1.5.3
I have another variable VarCurr
with following 1 value
1.8.1
I want to compare VarCurr
with VarExp
and want to echo SUCCESS
only when
VarCurr >= VarExp
I have written the following code but it it always returning 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
need to be >= the lowest value contained in VarExp
Upvotes: 2
Views: 339
Reputation: 203635
With GNU sort for -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
Upvotes: 3
Reputation: 46856
If you're using bash, you can use arrays. They make dealing with lists so much easier and safer. In addition, since you can't rely on feature availability like sort -V
to be portable, one option might be to convert your numbers to something that works better with bash comparisons. The following assumes that no numbers in your strings will be greater than 3 digits. Salt to taste.
#!/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
This uses the padsemver()
function to convert, say, 1.5.3
into 001005003
, which makes it compatible with a numeric comparison in test
or [[
. (The 10#
makes sure that a number starting with a 0 will be interpreted as decimal rather than octal.)
You could of course put the whole test into its own function rather than a stand-alone script if that was what you needed.
Upvotes: 3
Reputation: 24466
I recommend using a language that can properly objectify version objects and can understand major.minor.build.revision. Here's an example bash script which borrows from Perl for version parsing:
#!/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
Of course it might be more graceful just to write the whole thing in Perl.
Edit: Here's another example using 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
Upvotes: 4
Reputation: 133528
Could you please try following and let me know if this helps you.
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"."
}
}'
Output will be as follows.
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.
Assuming that your variable named varExp
has numeric values in new lines so by wrapping its value in "
will keep the new lines alive in it.
Upvotes: 2