Reputation: 2959
I have a file file1
which looks as below and carries current version and expected version numbers:
CurrV:1.5.2
ExpecV:1.8.1
I want to write a bash script to compare these two values and if ExpecV>=CurrV
then I should echo SUCCESS
, otherwise I should echo FAILURE
.
So far I have written this thing, but not sure how to proceed:
#!/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
Upvotes: 3
Views: 7048
Reputation: 52122
The question says that ExpecV>=CurrV
should be treated as success, but that does not make much sense (current version older than the expected one probably breaks something) and in your comments to this answer you allude to the desired behaviour being the other way around, so that's what this answer does.
This requires GNU sort for its -V
option (version sort):
if cmp -s <(cut -d: -f2 infile) <(cut -d: -f2 infile | sort -V); then
echo 'FAILURE'
else
echo 'SUCCESS'
fi
This requires that the line with CurrV
is always the first line. It extracts the parts after the colon with cut
and compares the unsorted (first process substitution <(...)
) to the version-sorted output (the second process substitution).
If they are the same, i.e., the version on the second line is greater than or equal to the one on the first line, the exit status of cmp
is successful and we print FAILURE
; if they aren't the same, this means that the sort
inverted the order and the expected version is less than the current version, so we print SUCCESS
.
The -s
flag is to suppress output of cmp
("silent"); we're only interested in the exit status.
If you have 1.5.2
and 1.8.1
already in separate variables CurrV
and ExpecV
, you can do something similar as follows:
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
This stores the two variables into versions
, separated by a newline, then compares the unsorted with the sorted sequence.
Upvotes: 3
Reputation: 20720
If you are on a Debian system, then using dpkg
is the easiest:
if dpkg --compare-versions $A lt $B
then
# $A < $B was true
fi
It supports all six comparison operators (see man dpkg
and search on compare-versions
).
One potential drawback: your versions have to be Debian compatible.
Upvotes: 4
Reputation: 8741
Both the answers of @benjamin-w and @Walter A are very concise. We can also compare sub-version by sub-version numerical values using a for loop as this:
#!/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
Upvotes: 1
Reputation: 19982
You can try
if [ $(echo "${CurrV}\n${ExpecV}"|sort|head -1) != "${CurrV}" ]; then ...
Upvotes: 5