উত্তর:
এখানে একটি খাঁটি বাশ সংস্করণ রয়েছে যা কোনও বাহ্যিক উপযোগের প্রয়োজন নেই:
#!/bin/bash
vercomp () {
if [[ $1 == $2 ]]
then
return 0
fi
local IFS=.
local i ver1=($1) ver2=($2)
# fill empty fields in ver1 with zeros
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++))
do
ver1[i]=0
done
for ((i=0; i<${#ver1[@]}; i++))
do
if [[ -z ${ver2[i]} ]]
then
# fill empty fields in ver2 with zeros
ver2[i]=0
fi
if ((10#${ver1[i]} > 10#${ver2[i]}))
then
return 1
fi
if ((10#${ver1[i]} < 10#${ver2[i]}))
then
return 2
fi
done
return 0
}
testvercomp () {
vercomp $1 $2
case $? in
0) op='=';;
1) op='>';;
2) op='<';;
esac
if [[ $op != $3 ]]
then
echo "FAIL: Expected '$3', Actual '$op', Arg1 '$1', Arg2 '$2'"
else
echo "Pass: '$1 $op $2'"
fi
}
# Run tests
# argument table format:
# testarg1 testarg2 expected_relationship
echo "The following tests should pass"
while read -r test
do
testvercomp $test
done << EOF
1 1 =
2.1 2.2 <
3.0.4.10 3.0.4.2 >
4.08 4.08.01 <
3.2.1.9.8144 3.2 >
3.2 3.2.1.9.8144 <
1.2 2.1 <
2.1 1.2 >
5.6.7 5.6.7 =
1.01.1 1.1.1 =
1.1.1 1.01.1 =
1 1.0 =
1.0 1 =
1.0.2.0 1.0.2 =
1..0 1.0 =
1.0 1..0 =
EOF
echo "The following test should fail (test the tester)"
testvercomp 1 1 '>'
পরীক্ষা চালান:
$ . ./vercomp
The following tests should pass
Pass: '1 = 1'
Pass: '2.1 < 2.2'
Pass: '3.0.4.10 > 3.0.4.2'
Pass: '4.08 < 4.08.01'
Pass: '3.2.1.9.8144 > 3.2'
Pass: '3.2 < 3.2.1.9.8144'
Pass: '1.2 < 2.1'
Pass: '2.1 > 1.2'
Pass: '5.6.7 = 5.6.7'
Pass: '1.01.1 = 1.1.1'
Pass: '1.1.1 = 1.01.1'
Pass: '1 = 1.0'
Pass: '1.0 = 1'
Pass: '1.0.2.0 = 1.0.2'
Pass: '1..0 = 1.0'
Pass: '1.0 = 1..0'
The following test should fail (test the tester)
FAIL: Expected '>', Actual '=', Arg1 '1', Arg2 '1'
Please don't use it for software or documentation, since it is incompatible with the GNU GPL
: / তবে +1 দুর্দান্ত কোডের জন্য
আপনার যদি কোরিউটিলস -7 (উবুন্টু কার্মিক তবে জন্টি নয়) থাকে তবে আপনার sort
কমান্ডের একটি -V
বিকল্প (সংস্করণ সাজান) থাকা উচিত যা আপনি তুলনা করতে ব্যবহার করতে পারেন:
verlte() {
[ "$1" = "`echo -e "$1\n$2" | sort -V | head -n1`" ]
}
verlt() {
[ "$1" = "$2" ] && return 1 || verlte $1 $2
}
verlte 2.5.7 2.5.6 && echo "yes" || echo "no" # no
verlt 2.4.10 2.4.9 && echo "yes" || echo "no" # no
verlt 2.4.8 2.4.10 && echo "yes" || echo "no" # yes
verlte 2.5.6 2.5.6 && echo "yes" || echo "no" # yes
verlt 2.5.6 2.5.6 && echo "yes" || echo "no" # no
brew install coreutils
। তারপরে উপরেরগুলিকে কেবল gsort ব্যবহারের জন্য পরিবর্তন করা উচিত।
sort
-V
বিকল্প নেই।
printf
পরিবর্তে এটি ব্যবহার করা ভাল echo -e
।
sort
রয়েছে -C
বা --check=silent
, যাতে আপনি লিখতে পারেন verlte() { printf '%s\n%s' "$1" "$2" | sort -C -V }
; এবং এর চেয়ে কম কঠোরভাবে চেক করা আরও সহজভাবে করা হয় verlt() { ! verlte "$2" "$1" }
।
এটি অর্জনের জন্য সম্ভবত সর্বজনীনভাবে সঠিক কোনও উপায় নেই। আপনি যদি ডেবিয়ান প্যাকেজ সিস্টেমে সংস্করণগুলির তুলনা করার চেষ্টা করছেনdpkg --compare-versions <first> <relation> <second>.
dpkg --compare-versions "1.0" "lt" "1.2"
মানে ১.২ এর চেয়ে কম 1.2। তুলনা ফলাফল যদি সত্য $?
হয় 0
তবে আপনি সরাসরি if
বিবৃতি দেওয়ার পরে এটি ব্যবহার করতে পারেন ।
জিএনইউ সাজানোর জন্য এটির একটি বিকল্প রয়েছে:
printf '2.4.5\n2.8\n2.4.5.1\n' | sort -V
দেয়:
2.4.5
2.4.5.1
2.8
echo -e "2.4.10\n2.4.9" | sort -n -t.
sort
-V
বিকল্প নেই।
printf '%s\n' "2.4.5" "2.8" "2.4.5.1" | sort -V
।
coreutils 7+
।
ভাল আপনি যদি ক্ষেত্রের সংখ্যা জানেন তবে আপনি -kn, n ব্যবহার করতে পারেন এবং একটি অতি-সহজ সমাধান পেতে পারেন
echo '2.4.5
2.8
2.4.5.1
2.10.2' | sort -t '.' -k 1,1 -k 2,2 -k 3,3 -k 4,4 -g
2.4.5
2.4.5.1
2.8
2.10.2
-t
বিকল্পটি কেবলমাত্র একক চরিত্রের ট্যাব গ্রহণ করে ... অন্যথায়, 2.4-r9
পাশাপাশি কাজ করবে। কী লজ্জাজনক: /
-g
করতে হয়েছিল -n
। কোন কারণ এই উদাহরণ না কেন? পার্শ্ব-নোটে ... একটি "এর চেয়ে বড়" ধরণের তুলনা সম্পাদন করতে, আপনি পরীক্ষা করতে পারেন যে পছন্দসই বাছাইটি প্রকৃত বাছাইয়ের মতো ... উদাহরণস্বরূপ desired="1.9\n1.11"; actual="$(echo -e $desired |sort -t '.' -k 1,1 -k 2,2 -g)";
এবং তারপরে যাচাই করুন if [ "$desired" = "$actual" ]
।
এটি সংস্করণে সর্বাধিক 4 টি ক্ষেত্রের জন্য।
$ function ver { printf "%03d%03d%03d%03d" $(echo "$1" | tr '.' ' '); }
$ [ $(ver 10.9) -lt $(ver 10.10) ] && echo hello
hello
printf "%03d%03d%03d%03d" $(echo "$1" | tr '.' '\n' | head -n 4)
head -n
কাজ করার জন্য, আমাকে পরিবর্তন করতে হয়েছিলtr '.' '\n'
tr
আউটপুট sed 's/\(^\| \)0\([0-9][0-9]*\)/\1\2/g'
যার মাধ্যমে এটি যত্ন নেবে (বরং
function version { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; }
যেমন ব্যবহার করা হয়:
if [ $(version $VAR) -ge $(version "6.2.0") ]; then
echo "Version is up to date"
fi
আপনি এখান.
থেকে নেওয়া নিম্নলিখিত অ্যালগরিদমে প্রদর্শিত হিসাবে পুনরাবৃত্তভাবে বিভক্ত এবং তুলনা করতে পারেন । সংস্করণগুলি একই হলে এটি 10, সংস্করণ 1 যদি 2 সংস্করণ 2 এবং 9 অন্যথায় 9 এর চেয়ে বড় হয় তবে তা ফেরত দেয়।
#!/bin/bash
do_version_check() {
[ "$1" == "$2" ] && return 10
ver1front=`echo $1 | cut -d "." -f -1`
ver1back=`echo $1 | cut -d "." -f 2-`
ver2front=`echo $2 | cut -d "." -f -1`
ver2back=`echo $2 | cut -d "." -f 2-`
if [ "$ver1front" != "$1" ] || [ "$ver2front" != "$2" ]; then
[ "$ver1front" -gt "$ver2front" ] && return 11
[ "$ver1front" -lt "$ver2front" ] && return 9
[ "$ver1front" == "$1" ] || [ -z "$ver1back" ] && ver1back=0
[ "$ver2front" == "$2" ] || [ -z "$ver2back" ] && ver2back=0
do_version_check "$ver1back" "$ver2back"
return $?
else
[ "$1" -gt "$2" ] && return 11 || return 9
fi
}
do_version_check "$1" "$2"
আমি এমন একটি ফাংশন বাস্তবায়ন করেছি যা ডেনিস উইলিয়ামসনের মতো একই ফলাফল দেয় তবে কম লাইন ব্যবহার করে। এটি প্রাথমিকভাবে একটি স্যানিটি চেক করে যা 1..0
তার পরীক্ষাগুলি থেকে ব্যর্থ হওয়ার কারণ হয়ে যায় (যা আমি যুক্তি দিয়ে বলব যে এটি হওয়া উচিত ) তবে তার অন্যান্য সমস্ত পরীক্ষাগুলি এই কোডের সাথে পাস করে:
#!/bin/bash
version_compare() {
if [[ $1 =~ ^([0-9]+\.?)+$ && $2 =~ ^([0-9]+\.?)+$ ]]; then
local l=(${1//./ }) r=(${2//./ }) s=${#l[@]}; [[ ${#r[@]} -gt ${#l[@]} ]] && s=${#r[@]}
for i in $(seq 0 $((s - 1))); do
[[ ${l[$i]} -gt ${r[$i]} ]] && return 1
[[ ${l[$i]} -lt ${r[$i]} ]] && return 2
done
return 0
else
echo "Invalid version number given"
exit 1
fi
}
এখানে একটি সাধারণ বাশ ফাংশন যা কোনও বাহ্যিক কমান্ড ব্যবহার করে না। এটি সংস্করণ স্ট্রিংয়ের জন্য কাজ করে যাগুলির মধ্যে তিনটি পর্যন্ত সংখ্যক অংশ রয়েছে - 3 টিরও কম জরিমানা। এটি আরও বেশি জন্য সহজে বাড়ানো যেতে পারে। এটা তোলে কার্যকরী =
, <
, <=
, >
, >=
, এবং !=
শর্ত।
#!/bin/bash
vercmp() {
version1=$1 version2=$2 condition=$3
IFS=. v1_array=($version1) v2_array=($version2)
v1=$((v1_array[0] * 100 + v1_array[1] * 10 + v1_array[2]))
v2=$((v2_array[0] * 100 + v2_array[1] * 10 + v2_array[2]))
diff=$((v2 - v1))
[[ $condition = '=' ]] && ((diff == 0)) && return 0
[[ $condition = '!=' ]] && ((diff != 0)) && return 0
[[ $condition = '<' ]] && ((diff > 0)) && return 0
[[ $condition = '<=' ]] && ((diff >= 0)) && return 0
[[ $condition = '>' ]] && ((diff < 0)) && return 0
[[ $condition = '>=' ]] && ((diff <= 0)) && return 0
return 1
}
পরীক্ষাটি এখানে:
for tv1 in '*' 1.1.1 2.5.3 7.3.0 0.5.7 10.3.9 8.55.32 0.0.1; do
for tv2 in 3.1.1 1.5.3 4.3.0 0.0.7 0.3.9 11.55.32 10.0.0 '*'; do
for c in '=' '>' '<' '>=' '<=' '!='; do
vercmp "$tv1" "$tv2" "$c" && printf '%s\n' "$tv1 $c $tv2 is true" || printf '%s\n' "$tv1 $c $tv2 is false"
done
done
done
পরীক্ষার ফলাফলের একটি উপসেট:
<snip>
* >= * is true
* <= * is true
* != * is true
1.1.1 = 3.1.1 is false
1.1.1 > 3.1.1 is false
1.1.1 < 3.1.1 is true
1.1.1 >= 3.1.1 is false
1.1.1 <= 3.1.1 is true
1.1.1 != 3.1.1 is true
1.1.1 = 1.5.3 is false
1.1.1 > 1.5.3 is false
1.1.1 < 1.5.3 is true
1.1.1 >= 1.5.3 is false
1.1.1 <= 1.5.3 is true
1.1.1 != 1.5.3 is true
1.1.1 = 4.3.0 is false
1.1.1 > 4.3.0 is false
<snip>
V
- খাঁটি বাশ সমাধান, কোনও বাহ্যিক উপযোগ প্রয়োজন।=
==
!=
<
<=
>
এবং>=
(অভিধান)1.5a < 1.5b
1.6 > 1.5b
if V 1.5 '<' 1.6; then ...
।<>
# Sample output
# Note: ++ (true) and __ (false) mean that V works correctly.
++ 3.6 '>' 3.5b
__ 2.5.7 '<=' 2.5.6
++ 2.4.10 '<' 2.5.9
__ 3.0002 '>' 3.0003.3
++ 4.0-RC2 '>' 4.0-RC1
<>
function V() # $1-a $2-op $3-$b
# Compare a and b as version strings. Rules:
# R1: a and b : dot-separated sequence of items. Items are numeric. The last item can optionally end with letters, i.e., 2.5 or 2.5a.
# R2: Zeros are automatically inserted to compare the same number of items, i.e., 1.0 < 1.0.1 means 1.0.0 < 1.0.1 => yes.
# R3: op can be '=' '==' '!=' '<' '<=' '>' '>=' (lexicographic).
# R4: Unrestricted number of digits of any item, i.e., 3.0003 > 3.0000004.
# R5: Unrestricted number of items.
{
local a=$1 op=$2 b=$3 al=${1##*.} bl=${3##*.}
while [[ $al =~ ^[[:digit:]] ]]; do al=${al:1}; done
while [[ $bl =~ ^[[:digit:]] ]]; do bl=${bl:1}; done
local ai=${a%$al} bi=${b%$bl}
local ap=${ai//[[:digit:]]} bp=${bi//[[:digit:]]}
ap=${ap//./.0} bp=${bp//./.0}
local w=1 fmt=$a.$b x IFS=.
for x in $fmt; do [ ${#x} -gt $w ] && w=${#x}; done
fmt=${*//[^.]}; fmt=${fmt//./%${w}s}
printf -v a $fmt $ai$bp; printf -v a "%s-%${w}s" $a $al
printf -v b $fmt $bi$ap; printf -v b "%s-%${w}s" $b $bl
case $op in
'<='|'>=' ) [ "$a" ${op:0:1} "$b" ] || [ "$a" = "$b" ] ;;
* ) [ "$a" $op "$b" ] ;;
esac
}
লাইন 1 : স্থানীয় ভেরিয়েবলগুলি সংজ্ঞায়িত করুন:
a
, op
, b
- তুলনা operands এবং অপারেটর, অর্থাত্, "3.6"> "3.5a"।al
, bl
- লেজ লেজগুলির লেজ লেজ a
এবং b
, প্রাথমিকভাবে, "6" এবং "5 এ" এর আরম্ভ করা হয়েছিল।লাইন 2, 3 : লেজ আইটেমগুলি থেকে বাম-ছাঁটাই অঙ্কগুলি তাই কেবলমাত্র অক্ষরগুলি থাকে, যদি কোনও হয়, যেমন, "" এবং "ক"।
লাইন 4 : ডান ট্রিম চিঠি থেকে a
এবং b
মাত্র স্থানীয় ভেরিয়েবল যেমন সাংখ্যিক আইটেম ক্রম ত্যাগ করার ai
এবংbi
, অর্থাত্, "3.6" এবং "3.5"। উল্লেখযোগ্য উদাহরণ: "4.01-আরসি 2"> "4.01-আরসি 1" ফলন করে আইআই = "4.01" আল = "- আরসি 2" এবং দ্বি = "4.01" ব্লু "" - আরসি 1 "।
লাইন 6 : স্থানীয় ভেরিয়েবলগুলি সংজ্ঞায়িত করুন:
ap
, bp
- জন্য শূন্য ডান-paddings ai
এবং bi
। শুধুমাত্র আন্ত আইটেমটি বিন্দু, যার সংখ্যা উপাদানের সংখ্যা সমান রেখে শুরু a
এবং b
যথাক্রমে।লাইন :: প্যাডিং মাস্কগুলি তৈরি করতে প্রতিটি বিন্দুর পরে "0" যুক্ত করুন।
লাইন 9 : স্থানীয় ভেরিয়েবল:
w
- আইটেম প্রস্থfmt
- মুদ্রণ ফর্ম্যাট স্ট্রিং, গণনা করাx
- অস্থায়ীIFS=.
বাশ '' এ পরিবর্তিত ভেরিয়েবলের সাথে ।লাইন 10 : গণনা করুন w
, সর্বাধিক আইটেম প্রস্থ, যা অভিধান সংক্রান্ত তুলনার জন্য আইটেমগুলিকে সারিবদ্ধ করতে ব্যবহৃত হবে। আমাদের উদাহরণে ডাব্লু = 2।
লাইন 11 : প্রতিটি অক্ষর , অর্থাৎ "3.6"> "3.5a" "% 2s% 2s% 2s% 2s" এর $a.$b
সাথে প্রতিস্থাপন করে %${w}s
প্রিন্টফ প্রান্তিককরণ বিন্যাস তৈরি করুন ।
লাইন 12 : "printf -v a" ভেরিয়েবলের মান নির্ধারণ করে a
। এটি a=sprintf(...)
অনেক প্রোগ্রামিং ভাষায় সমান । নোট করুন যে এখানে, আইএফএস = এর প্রভাব দ্বারা। যুক্তি printf
পৃথক আইটেম বিভক্ত।
প্রথম printf
আইটেমগুলিতে a
ফাঁক দিয়ে বাম-প্যাডযুক্ত রয়েছে যখন bp
ফলস্বরূপ স্ট্রিংটি a
অনুরূপভাবে ফর্ম্যাটের সাথে তুলনামূলকভাবে তুলনামূলকভাবে করা যায় তা নিশ্চিত করার জন্য পর্যাপ্ত আইটেমগুলি সংযুক্ত করা হয় whileb
।
মনে রাখবেন আমরা যোগ bp
- না ap
করার ai
কারণ ap
এবং bp
বিভিন্ন lenghts থাকতে পারে, তাই এই ফলাফল a
এবং b
সমান লেন্থ হচ্ছে।
দ্বিতীয় সঙ্গে printf
আমরা চিঠি অংশ যোগ al
করতে a
অর্থপূর্ণ তুলনা সক্ষম করতে যথেষ্ট প্যাডিং সঙ্গে। এখন a
তুলনা করার জন্য প্রস্তুত b
।
লাইন 13 : লাইন 12 হিসাবে একই কিন্তু b
।
লাইন 15 : অ-অন্তর্নির্মিত ( <=
এবং >=
) এবং অন্তর্নির্মিত অপারেটরগুলির মধ্যে বিভাজক তুলনা কেস ।
লাইন 16 : যদি তুলনা অপারেটরটি হয় যথাক্রমে - এর <=
জন্য পরীক্ষা করা a<b or a=b
হয়>=
a<b or a=b
লাইন 17 : বিল্ট-ইন তুলনা অপারেটরগুলির জন্য পরীক্ষা Test
<>
# All tests
function P { printf "$@"; }
function EXPECT { printf "$@"; }
function CODE { awk $BASH_LINENO'==NR{print " "$2,$3,$4}' "$0"; }
P 'Note: ++ (true) and __ (false) mean that V works correctly.\n'
V 2.5 '!=' 2.5 && P + || P _; EXPECT _; CODE
V 2.5 '=' 2.5 && P + || P _; EXPECT +; CODE
V 2.5 '==' 2.5 && P + || P _; EXPECT +; CODE
V 2.5a '==' 2.5b && P + || P _; EXPECT _; CODE
V 2.5a '<' 2.5b && P + || P _; EXPECT +; CODE
V 2.5a '>' 2.5b && P + || P _; EXPECT _; CODE
V 2.5b '>' 2.5a && P + || P _; EXPECT +; CODE
V 2.5b '<' 2.5a && P + || P _; EXPECT _; CODE
V 3.5 '<' 3.5b && P + || P _; EXPECT +; CODE
V 3.5 '>' 3.5b && P + || P _; EXPECT _; CODE
V 3.5b '>' 3.5 && P + || P _; EXPECT +; CODE
V 3.5b '<' 3.5 && P + || P _; EXPECT _; CODE
V 3.6 '<' 3.5b && P + || P _; EXPECT _; CODE
V 3.6 '>' 3.5b && P + || P _; EXPECT +; CODE
V 3.5b '<' 3.6 && P + || P _; EXPECT +; CODE
V 3.5b '>' 3.6 && P + || P _; EXPECT _; CODE
V 2.5.7 '<=' 2.5.6 && P + || P _; EXPECT _; CODE
V 2.4.10 '<' 2.4.9 && P + || P _; EXPECT _; CODE
V 2.4.10 '<' 2.5.9 && P + || P _; EXPECT +; CODE
V 3.4.10 '<' 2.5.9 && P + || P _; EXPECT _; CODE
V 2.4.8 '>' 2.4.10 && P + || P _; EXPECT _; CODE
V 2.5.6 '<=' 2.5.6 && P + || P _; EXPECT +; CODE
V 2.5.6 '>=' 2.5.6 && P + || P _; EXPECT +; CODE
V 3.0 '<' 3.0.3 && P + || P _; EXPECT +; CODE
V 3.0002 '<' 3.0003.3 && P + || P _; EXPECT +; CODE
V 3.0002 '>' 3.0003.3 && P + || P _; EXPECT _; CODE
V 3.0003.3 '<' 3.0002 && P + || P _; EXPECT _; CODE
V 3.0003.3 '>' 3.0002 && P + || P _; EXPECT +; CODE
V 4.0-RC2 '>' 4.0-RC1 && P + || P _; EXPECT +; CODE
V 4.0-RC2 '<' 4.0-RC1 && P + || P _; EXPECT _; CODE
আমি ব্যাসিবক্সের সাথে এম্বেড থাকা লিনাক্স (ইয়োক্টো) ব্যবহার করছি। ব্যাসিবক্সেরsort
কোনও -V
বিকল্প নেই (তবে ব্যাসিবক্সexpr match
নিয়মিত প্রকাশ করতে পারে)। সুতরাং আমার একটি বাশ সংস্করণ তুলনা করতে হবে যা সেই সীমাবদ্ধতার সাথে কাজ করেছিল।
"প্রাকৃতিক সাজানোর" ধরণের অ্যালগরিদম ব্যবহার করে তুলনা করার জন্য আমি নিম্নলিখিতগুলি ( ডেনিস উইলিয়ামসনের উত্তরের মতো ) তৈরি করেছি । এটি স্ট্রিংকে সংখ্যাসূচক অংশ এবং অ-সংখ্যাীয় অংশে বিভক্ত করে; এটি সংখ্যার অংশগুলিকে সংখ্যার সাথে তুলনা করে (সুতরাং 10
এর চেয়েও বড় 9
), এবং সংখ্যাসূচক অংশগুলিকে একটি সরল ASCII তুলনা হিসাবে তুলনা করে।
ascii_frag() {
expr match "$1" "\([^[:digit:]]*\)"
}
ascii_remainder() {
expr match "$1" "[^[:digit:]]*\(.*\)"
}
numeric_frag() {
expr match "$1" "\([[:digit:]]*\)"
}
numeric_remainder() {
expr match "$1" "[[:digit:]]*\(.*\)"
}
vercomp_debug() {
OUT="$1"
#echo "${OUT}"
}
# return 1 for $1 > $2
# return 2 for $1 < $2
# return 0 for equal
vercomp() {
local WORK1="$1"
local WORK2="$2"
local NUM1="", NUM2="", ASCII1="", ASCII2=""
while true; do
vercomp_debug "ASCII compare"
ASCII1=`ascii_frag "${WORK1}"`
ASCII2=`ascii_frag "${WORK2}"`
WORK1=`ascii_remainder "${WORK1}"`
WORK2=`ascii_remainder "${WORK2}"`
vercomp_debug "\"${ASCII1}\" remainder \"${WORK1}\""
vercomp_debug "\"${ASCII2}\" remainder \"${WORK2}\""
if [ "${ASCII1}" \> "${ASCII2}" ]; then
vercomp_debug "ascii ${ASCII1} > ${ASCII2}"
return 1
elif [ "${ASCII1}" \< "${ASCII2}" ]; then
vercomp_debug "ascii ${ASCII1} < ${ASCII2}"
return 2
fi
vercomp_debug "--------"
vercomp_debug "Numeric compare"
NUM1=`numeric_frag "${WORK1}"`
NUM2=`numeric_frag "${WORK2}"`
WORK1=`numeric_remainder "${WORK1}"`
WORK2=`numeric_remainder "${WORK2}"`
vercomp_debug "\"${NUM1}\" remainder \"${WORK1}\""
vercomp_debug "\"${NUM2}\" remainder \"${WORK2}\""
if [ -z "${NUM1}" -a -z "${NUM2}" ]; then
vercomp_debug "blank 1 and blank 2 equal"
return 0
elif [ -z "${NUM1}" -a -n "${NUM2}" ]; then
vercomp_debug "blank 1 less than non-blank 2"
return 2
elif [ -n "${NUM1}" -a -z "${NUM2}" ]; then
vercomp_debug "non-blank 1 greater than blank 2"
return 1
fi
if [ "${NUM1}" -gt "${NUM2}" ]; then
vercomp_debug "num ${NUM1} > ${NUM2}"
return 1
elif [ "${NUM1}" -lt "${NUM2}" ]; then
vercomp_debug "num ${NUM1} < ${NUM2}"
return 2
fi
vercomp_debug "--------"
done
}
এটি আরও জটিল সংস্করণ সংখ্যার সাথে তুলনা করতে পারে
1.2-r3
বনাম 1.2-r4
1.2rc3
বনাম 1.2r4
মনে রাখবেন যে ডেনিস উইলিয়ামসনের উত্তরের কয়েকটি কর্নারের ক্ষেত্রে একই ফলাফলটি ফিরে আসে না । নির্দিষ্টভাবে:
1 1.0 <
1.0 1 >
1.0.2.0 1.0.2 >
1..0 1.0 >
1.0 1..0 <
তবে এগুলি কর্নার কেস এবং আমি মনে করি ফলাফলগুলি এখনও যুক্তিসঙ্গত।
$ for OVFTOOL_VERSION in "4.2.0" "4.2.1" "5.2.0" "3.2.0" "4.1.9" "4.0.1" "4.3.0" "4.5.0" "4.2.1" "30.1.0" "4" "5" "4.1" "4.3"
> do
> if [ $(echo "$OVFTOOL_VERSION 4.2.0" | tr " " "\n" | sort --version-sort | head -n 1) = 4.2.0 ]; then
> echo "$OVFTOOL_VERSION is >= 4.2.0";
> else
> echo "$OVFTOOL_VERSION is < 4.2.0";
> fi
> done
4.2.0 is >= 4.2.0
4.2.1 is >= 4.2.0
5.2.0 is >= 4.2.0
3.2.0 is < 4.2.0
4.1.9 is < 4.2.0
4.0.1 is < 4.2.0
4.3.0 is >= 4.2.0
4.5.0 is >= 4.2.0
4.2.1 is >= 4.2.0
30.1.0 is >= 4.2.0
4 is < 4.2.0
5 is >= 4.2.0
4.1 is < 4.2.0
4.3 is >= 4.2.0
--check=silent
সাহায্যে আপনি কোনও প্রয়োজন ছাড়াই test
এই জাতীয় ব্যবহার করতে পারেন : if printf '%s\n%s' 4.2.0 "$OVFTOOL_VERSION" | sort --version-sort -C
এটিও একটি pure bash
সমাধান, কারণ প্রিন্টফ বাশ অন্তর্নির্মিত।
function ver()
# Description: use for comparisons of version strings.
# $1 : a version string of form 1.2.3.4
# use: (( $(ver 1.2.3.4) >= $(ver 1.2.3.3) )) && echo "yes" || echo "no"
{
printf "%02d%02d%02d%02d" ${1//./ }
}
পুরানো সংস্করণ / ব্যস্তবক্সের জন্য sort
। সাধারণ ফর্ম মোটামুটি ফলাফল সরবরাহ করে এবং প্রায়শই কাজ করে।
sort -n
এটি এমন সংস্করণে বিশেষ উপযোগী যার মধ্যে আলফা চিহ্ন রয়েছে
10.c.3
10.a.4
2.b.5
এ কেমন? কাজ মনে হচ্ছে?
checkVersion() {
subVer1=$1
subVer2=$2
[ "$subVer1" == "$subVer2" ] && echo "Version is same"
echo "Version 1 is $subVer1"
testVer1=$subVer1
echo "Test version 1 is $testVer1"
x=0
while [[ $testVer1 != "" ]]
do
((x++))
testVer1=`echo $subVer1|cut -d "." -f $x`
echo "testVer1 now is $testVer1"
testVer2=`echo $subVer2|cut -d "." -f $x`
echo "testVer2 now is $testVer2"
if [[ $testVer1 -gt $testVer2 ]]
then
echo "$ver1 is greater than $ver2"
break
elif [[ "$testVer2" -gt "$testVer1" ]]
then
echo "$ver2 is greater than $ver1"
break
fi
echo "This is the sub verion for first value $testVer1"
echo "This is the sub verion for second value $testVer2"
done
}
ver1=$1
ver2=$2
checkVersion "$ver1" "$ver2"
বাহ্যিক কল ছাড়াই এখানে আরও খাঁটি বাশ সমাধান রয়েছে:
#!/bin/bash
function version_compare {
IFS='.' read -ra ver1 <<< "$1"
IFS='.' read -ra ver2 <<< "$2"
[[ ${#ver1[@]} -gt ${#ver2[@]} ]] && till=${#ver1[@]} || till=${#ver2[@]}
for ((i=0; i<${till}; i++)); do
local num1; local num2;
[[ -z ${ver1[i]} ]] && num1=0 || num1=${ver1[i]}
[[ -z ${ver2[i]} ]] && num2=0 || num2=${ver2[i]}
if [[ $num1 -gt $num2 ]]; then
echo ">"; return 0
elif
[[ $num1 -lt $num2 ]]; then
echo "<"; return 0
fi
done
echo "="; return 0
}
echo "${1} $(version_compare "${1}" "${2}") ${2}"
এবং আরও সহজ সমাধান রয়েছে, আপনি যদি নিশ্চিত হন যে প্রথম সংস্করণের পরে প্রশ্নের মধ্যে থাকা সংস্করণগুলিতে শীর্ষস্থানীয় জিরো নেই:
#!/bin/bash
function version_compare {
local ver1=${1//.}
local ver2=${2//.}
if [[ $ver1 -gt $ver2 ]]; then
echo ">"; return 0
elif
[[ $ver1 -lt $ver2 ]]; then
echo "<"; return 0
fi
echo "="; return 0
}
echo "${1} $(version_compare "${1}" "${2}") ${2}"
এটি 1.2.3 বনাম 1.3.1 বনাম 0.9.7 এর মতো কোনও কিছুর জন্য কাজ করবে, তবে 1.2.3 বনাম 1.2.3.0 বা 1.01.1 বনাম 1.1.1 এর সাথে কাজ করবে না
4.4.4 > 44.3
এখানে শীর্ষ উত্তরের (ডেনিসের) সংশোধন রয়েছে যা আরও সংক্ষিপ্ত এবং একক তুলনার সাথে <= এবং> = কার্যকর করা সহজ করার জন্য একটি ভিন্ন রিটার্ন ভ্যালু স্কিম ব্যবহার করে। এটি প্রথম অক্ষরটির পরে সমস্ত কিছু তুলনা করে [0-9।] অভিধানে নয়, সুতরাং 1.0rc1 <1.0rc2।
# Compares two tuple-based, dot-delimited version numbers a and b (possibly
# with arbitrary string suffixes). Returns:
# 1 if a<b
# 2 if equal
# 3 if a>b
# Everything after the first character not in [0-9.] is compared
# lexicographically using ASCII ordering if the tuple-based versions are equal.
compare-versions() {
if [[ $1 == $2 ]]; then
return 2
fi
local IFS=.
local i a=(${1%%[^0-9.]*}) b=(${2%%[^0-9.]*})
local arem=${1#${1%%[^0-9.]*}} brem=${2#${2%%[^0-9.]*}}
for ((i=0; i<${#a[@]} || i<${#b[@]}; i++)); do
if ((10#${a[i]:-0} < 10#${b[i]:-0})); then
return 1
elif ((10#${a[i]:-0} > 10#${b[i]:-0})); then
return 3
fi
done
if [ "$arem" '<' "$brem" ]; then
return 1
elif [ "$arem" '>' "$brem" ]; then
return 3
fi
return 2
}
আমি আর একটি তুলনামূলক ফাংশন প্রয়োগ করেছি। এর একটির দুটি নির্দিষ্ট প্রয়োজনীয়তা ছিল: (i) আমি চাইনি return 1
বরং ব্যবহারের মাধ্যমে ফাংশনটি ব্যর্থ হয় echo
; (ii) যেহেতু আমরা গিট সংগ্রহস্থল সংস্করণ "1.0" থেকে সংস্করণগুলি পুনরুদ্ধার করছি "1.0" "এর চেয়ে বড় হওয়া উচিত, যার অর্থ" 1.0 "ট্রাঙ্ক থেকে এসেছে।
function version_compare {
IFS="." read -a v_a <<< "$1"
IFS="." read -a v_b <<< "$2"
while [[ -n "$v_a" || -n "$v_b" ]]; do
[[ -z "$v_a" || "$v_a" -gt "$v_b" ]] && echo 1 && return
[[ -z "$v_b" || "$v_b" -gt "$v_a" ]] && echo -1 && return
v_a=("${v_a[@]:1}")
v_b=("${v_b[@]:1}")
done
echo 0
}
মন্তব্য এবং উন্নত পরামর্শ নির্দ্বিধায়।
সংস্করণের সীমাবদ্ধতাগুলি পরীক্ষা করতে আপনি সংস্করণ সংস্করণ ব্যবহার করতে পারেন
$ version ">=1.0, <2.0" "1.7"
$ go version | version ">=1.9"
বাশ লিপির উদাহরণ:
#!/bin/bash
if `version -b ">=9.0.0" "$(gcc --version)"`; then
echo "gcc version satisfies constraints >=9.0.0"
else
echo "gcc version doesn't satisfies constraints >=9.0.0"
fi
আমি অতিরিক্ত এসে (এবং সংক্ষিপ্ত এবং সহজ) উত্তর যুক্ত করতে, এই সমস্যাটি সমাধান করেছি এবং এই সমস্যার সমাধান করেছি ...
প্রথম দ্রষ্টব্য, বর্ধিত শেল তুলনা ব্যর্থ হয়েছে কারণ আপনি ইতিমধ্যে জানতে পারেন ...
if [[ 1.2.0 < 1.12.12 ]]; then echo true; else echo false; fi
false
সংস্করণ এবং সরল বাশ স্ট্রিং তুলনাটি অর্ডার করতে বাছাই -t '.'- g (বা কনক দ্বারা উল্লিখিত বাছাই-ভি) ব্যবহার করে আমি একটি সমাধান পেয়েছি। ইনপুট ফাইলটিতে 3 এবং 4 কলামে সংস্করণ রয়েছে যা আমি তুলনা করতে চাই। এই তালিকার মধ্য দিয়ে পুনরাবৃত্তি একটি মিলকে সনাক্ত করে বা যদি অন্যটির চেয়ে বড় হয়। আশা করি এটি এখনও যতটা সম্ভব সহজ ব্যাশ ব্যবহার করে এটি করতে খুঁজছেন এমন কাউকে সহায়তা করতে পারে।
while read l
do
#Field 3 contains version on left to compare (change -f3 to required column).
kf=$(echo $l | cut -d ' ' -f3)
#Field 4 contains version on right to compare (change -f4 to required column).
mp=$(echo $l | cut -d ' ' -f4)
echo 'kf = '$kf
echo 'mp = '$mp
#To compare versions m.m.m the two can be listed and sorted with a . separator and the greater version found.
gv=$(echo -e $kf'\n'$mp | sort -t'.' -g | tail -n 1)
if [ $kf = $mp ]; then
echo 'Match Found: '$l
elif [ $kf = $gv ]; then
echo 'Karaf feature file version is greater '$l
elif [ $mp = $gv ]; then
echo 'Maven pom file version is greater '$l
else
echo 'Comparison error '$l
fi
done < features_and_pom_versions.tmp.txt
বাছাই করা ধারণার জন্য ব্লগকে ধন্যবাদ ... রেফ: http://bkhome.org/blog/?view বিস্তারিত বিবরণ=02199
### the answer is does we second argument is higher
function _ver_higher {
ver=`echo -ne "$1\n$2" |sort -Vr |head -n1`
if [ "$2" == "$1" ]; then
return 1
elif [ "$2" == "$ver" ]; then
return 0
else
return 1
fi
}
if _ver_higher $1 $2; then
echo higher
else
echo same or less
fi
এটি বেশ সহজ এবং ছোট।
echo -ne "$1\n$2"
সঙ্গে printf '%s\n ' "$1" "$2"
। এছাড়াও $()
ব্যাকটিক্সের পরিবর্তে ব্যবহার করা ভাল ।
ডেনিসের সমাধানটির জন্য ধন্যবাদ, আমরা তুলনামূলক অপারেটরগুলিকে '>', '<', '=', '==', '<=', এবং '> =' অনুমতি দেওয়ার জন্য এটি বাড়িয়ে দিতে পারি।
# compver ver1 '=|==|>|<|>=|<=' ver2
compver() {
local op
vercomp $1 $3
case $? in
0) op='=';;
1) op='>';;
2) op='<';;
esac
[[ $2 == *$op* ]] && return 0 || return 1
}
এরপরে আমরা তুলনামূলক অপারেটরগুলি এর মত প্রকাশে ব্যবহার করতে পারি:
compver 1.7 '<=' 1.8
compver 1.7 '==' 1.7
compver 1.7 '=' 1.7
এবং ফলাফলের সত্য / মিথ্যা পরীক্ষা করুন, যেমন:
if compver $ver1 '>' $ver2; then
echo "Newer"
fi
এখানে আর একটি খাঁটি বাশ সংস্করণ গ্রহণযোগ্য উত্তরের চেয়ে ছোট rather এটি কেবলমাত্র কোনও সংস্করণ "ন্যূনতম সংস্করণ" এর চেয়ে কম বা সমান কিনা তা যাচাই করে এবং এটি বর্ণানুক্রমিকভাবে বর্ণানুক্রমিক অনুক্রমগুলি পরীক্ষা করে দেখায় যা প্রায়শই ভুল ফলাফল দেয় (একটি সাধারণ উদাহরণ দেওয়ার জন্য "স্ন্যাপশট" "রিলিজ" এর পরে নয়) । এটি মেজর / অপ্রাপ্তবয়স্কদের জন্য ভাল কাজ করবে।
is_number() {
case "$BASH_VERSION" in
3.1.*)
PATTERN='\^\[0-9\]+\$'
;;
*)
PATTERN='^[0-9]+$'
;;
esac
[[ "$1" =~ $PATTERN ]]
}
min_version() {
if [[ $# != 2 ]]
then
echo "Usage: min_version current minimum"
return
fi
A="${1%%.*}"
B="${2%%.*}"
if [[ "$A" != "$1" && "$B" != "$2" && "$A" == "$B" ]]
then
min_version "${1#*.}" "${2#*.}"
else
if is_number "$A" && is_number "$B"
then
[[ "$A" -ge "$B" ]]
else
[[ ! "$A" < "$B" ]]
fi
fi
}
আরেকটি পদ্ধতির (@ জয়েনিসের পরিবর্তিত সংস্করণ) যা প্রশ্নে জিজ্ঞাসা করা বিন্দু সংস্করণগুলির তুলনা করে
(যেমন "1.2", "2.3.4", "1.0", "1.10.1", ইত্যাদি)।
পজিশনের সর্বাধিক সংখ্যা আগেই জানতে হবে। পদ্ধতির সর্বোচ্চ 3 সংস্করণ অবস্থান আশা করে।
expr $(printf "$1\n$2" | sort -t '.' -k 1,1 -k 2,2 -k 3,3 -g | sed -n 2p) != $2
উদাহরণস্বরূপ ব্যবহার:
expr $(printf "1.10.1\n1.7" | sort -t '.' -k 1,1 -k 2,2 -k 3,3 -g | sed -n 2p) != "1.7"
রিটার্ন: ১.১০.১ থেকে ১. 1 এর চেয়ে বড়
expr $(printf "1.10.1\n1.11" | sort -t '.' -k 1,1 -k 2,2 -k 3,3 -g | sed -n 2p) != "1.11"
রিটার্ন: ০.১১.১.১ থেকে ০.১১ কম
ডেনিস উইলিয়ামসন পোস্ট করেছেন এমন উত্তরের উপর ভিত্তি করে একটি খাঁটি বাশ সমাধান যা সংশোধনগুলি (যেমন '1.0-r1') সমর্থন করে । '-RC1' এর মতো স্টাফ সমর্থন করতে বা নিয়মিত এক্সপ্রেশন পরিবর্তন করে আরও জটিল স্ট্রিং থেকে সংস্করণটি বের করতে সহজেই এটি পরিবর্তন করা যেতে পারে।
বাস্তবায়ন সম্পর্কিত বিশদগুলির জন্য, দয়া করে ইন-কোড মন্তব্যগুলি দেখুন এবং / অথবা অন্তর্ভুক্ত ডিবাগ কোডটি সক্ষম করুন:
#!/bin/bash
# Compare two version strings [$1: version string 1 (v1), $2: version string 2 (v2)]
# Return values:
# 0: v1 == v2
# 1: v1 > v2
# 2: v1 < v2
# Based on: https://stackoverflow.com/a/4025065 by Dennis Williamson
function compare_versions() {
# Trivial v1 == v2 test based on string comparison
[[ "$1" == "$2" ]] && return 0
# Local variables
local regex="^(.*)-r([0-9]*)$" va1=() vr1=0 va2=() vr2=0 len i IFS="."
# Split version strings into arrays, extract trailing revisions
if [[ "$1" =~ ${regex} ]]; then
va1=(${BASH_REMATCH[1]})
[[ -n "${BASH_REMATCH[2]}" ]] && vr1=${BASH_REMATCH[2]}
else
va1=($1)
fi
if [[ "$2" =~ ${regex} ]]; then
va2=(${BASH_REMATCH[1]})
[[ -n "${BASH_REMATCH[2]}" ]] && vr2=${BASH_REMATCH[2]}
else
va2=($2)
fi
# Bring va1 and va2 to same length by filling empty fields with zeros
(( ${#va1[@]} > ${#va2[@]} )) && len=${#va1[@]} || len=${#va2[@]}
for ((i=0; i < len; ++i)); do
[[ -z "${va1[i]}" ]] && va1[i]="0"
[[ -z "${va2[i]}" ]] && va2[i]="0"
done
# Append revisions, increment length
va1+=($vr1)
va2+=($vr2)
len=$((len+1))
# *** DEBUG ***
#echo "TEST: '${va1[@]} (?) ${va2[@]}'"
# Compare version elements, check if v1 > v2 or v1 < v2
for ((i=0; i < len; ++i)); do
if (( 10#${va1[i]} > 10#${va2[i]} )); then
return 1
elif (( 10#${va1[i]} < 10#${va2[i]} )); then
return 2
fi
done
# All elements are equal, thus v1 == v2
return 0
}
# Test compare_versions [$1: version string 1, $2: version string 2, $3: expected result]
function test_compare_versions() {
local op
compare_versions "$1" "$2"
case $? in
0) op="==" ;;
1) op=">" ;;
2) op="<" ;;
esac
if [[ "$op" == "$3" ]]; then
echo -e "\e[1;32mPASS: '$1 $op $2'\e[0m"
else
echo -e "\e[1;31mFAIL: '$1 $3 $2' (result: '$1 $op $2')\e[0m"
fi
}
echo -e "\nThe following tests should pass:"
while read -r test; do
test_compare_versions $test
done << EOF
1 1 ==
2.1 2.2 <
3.0.4.10 3.0.4.2 >
4.08 4.08.01 <
3.2.1.9.8144 3.2 >
3.2 3.2.1.9.8144 <
1.2 2.1 <
2.1 1.2 >
5.6.7 5.6.7 ==
1.01.1 1.1.1 ==
1.1.1 1.01.1 ==
1 1.0 ==
1.0 1 ==
1.0.2.0 1.0.2 ==
1..0 1.0 ==
1.0 1..0 ==
1.0-r1 1.0-r3 <
1.0-r9 2.0 <
3.0-r15 3.0-r9 >
...-r1 ...-r2 <
2.0-r1 1.9.8.21-r2 >
1.0 3.8.9.32-r <
-r -r3 <
-r3 -r >
-r3 -r3 ==
-r -r ==
0.0-r2 0.0.0.0-r2 ==
1.0.0.0-r2 1.0-r2 ==
0.0.0.1-r7 -r9 >
0.0-r0 0 ==
1.002.0-r6 1.2.0-r7 <
001.001-r2 1.1-r2 ==
5.6.1-r0 5.6.1 ==
EOF
echo -e "\nThe following tests should fail:"
while read -r test; do
test_compare_versions $test
done << EOF
1 1 >
3.0.5-r5 3..5-r5 >
4.9.21-r3 4.8.22-r9 <
1.0-r 1.0-r1 ==
-r 1.0-r >
-r1 0.0-r1 <
-r2 0-r2 <
EOF
echo -e "\nThe following line should be empty (local variables test):"
echo "$op $regex $va1 $vr1 $va2 $vr2 $len $i $IFS"
বাহ ... এটি পুরানো প্রশ্নের তালিকার নীচে, তবে আমি মনে করি এটি একটি সুন্দর মার্জিত উত্তর। প্রথম নিজস্ব অ্যারের প্রতিটি বিন্দু বিভাজিত সংস্করণ রূপান্তর করে, শেল প্যারামিটার সম্প্রসারণ (দেখুন ব্যবহার শেল প্যারামিটার সম্প্রসারণ )।
v1="05.2.3" # some evil examples that work here
v2="7.001.0.0"
declare -a v1_array=(${v1//./ })
declare -a v2_array=(${v2//./ })
এখন দুটি অ্যারে সংখ্যার স্ট্রিং হিসাবে অগ্রাধিকার ক্রমে সংস্করণ নম্বর রয়েছে। উপরের প্রচুর সমাধানগুলি আপনাকে সেখান থেকে নিয়ে যায়, তবে এটি সমস্ত পর্যবেক্ষণ থেকে প্রাপ্ত যে সংস্করণটির স্ট্রিং একটি স্বেচ্ছাচারিত বেসের সাথে কেবল একটি পূর্ণসংখ্যা। আমরা প্রথম অসম সংখ্যা (যেমন স্ট্রিংয়ের অক্ষরের জন্য স্ট্রিম্পের মতো করে) সন্ধান করতে পারি।
compare_version() {
declare -a v1_array=(${1//./ })
declare -a v2_array=(${2//./ })
while [[ -nz $v1_array ]] || [[ -nz $v2_array ]]; do
let v1_val=${v1_array:-0} # this will remove any leading zeros
let v2_val=${v2_array:-0}
let result=$((v1_val-v2_val))
if (( result != 0 )); then
echo $result
return
fi
v1_array=("${v1_array[@]:1}") # trim off the first "digit". it doesn't help
v2_array=("${v2_array[@]:1}")
done
# if we get here, both the arrays are empty and neither has been numerically
# different, which is equivalent to the two versions being equal
echo 0
return
}
প্রথম সংস্করণটি দ্বিতীয়টির চেয়ে কম হলে এটি একটি নেতিবাচক সংখ্যার প্রতিধ্বনি দেয়, সমান হলে একটি শূন্য এবং যদি প্রথম সংস্করণটি বেশি হয় তবে ধনাত্মক সংখ্যা থাকে। কিছু আউটপুট:
$ compare_version 1 1.2
-2
$ compare_version "05.1.3" "5.001.03.0.0.0.1"
-1
$ compare_version "05.1.3" "5.001.03.0.0.0"
0
$ compare_version "05.1.3" "5.001.03.0"
0
$ compare_version "05.1.3" "5.001.30.0"
-27
$ compare_version "05.2.3" "7.001.0.0"
-2
$ compare_version "05.1.3" "5.001.30.0"
-27
$ compare_version "7.001.0.0" "05.1.3"
2
".2" বা "3.0" এর মতো কেস ডিজাইনারেট করুন। কাজ করবেন না (অপরিবর্তিত ফলাফল), এবং যদি অ-সংখ্যাসূচক অক্ষর উপস্থিত থাকে তবে ''। এটি ব্যর্থ হতে পারে (পরীক্ষিত হয়নি) তবে অবশ্যই এটি অপরিশোধিত হবে। সুতরাং এটি একটি স্যানিটাইজিং ফাংশন বা বৈধ ফর্ম্যাটের জন্য উপযুক্ত পরীক্ষার সাথে যুক্ত করা উচিত। এছাড়াও, আমি কিছু টুইট করার সাথে নিশ্চিত, অতিরিক্ত অতিরিক্ত লাগেজ ছাড়া এটি আরও শক্তিশালী করা যেতে পারে।
function version_compare () {
function sub_ver () {
local len=${#1}
temp=${1%%"."*} && indexOf=`echo ${1%%"."*} | echo ${#temp}`
echo -e "${1:0:indexOf}"
}
function cut_dot () {
local offset=${#1}
local length=${#2}
echo -e "${2:((++offset)):length}"
}
if [ -z "$1" ] || [ -z "$2" ]; then
echo "=" && exit 0
fi
local v1=`echo -e "${1}" | tr -d '[[:space:]]'`
local v2=`echo -e "${2}" | tr -d '[[:space:]]'`
local v1_sub=`sub_ver $v1`
local v2_sub=`sub_ver $v2`
if (( v1_sub > v2_sub )); then
echo ">"
elif (( v1_sub < v2_sub )); then
echo "<"
else
version_compare `cut_dot $v1_sub $v1` `cut_dot $v2_sub $v2`
fi
}
### Usage:
version_compare "1.2.3" "1.2.4"
# Output: <
ক্রেডিট @ শেলম্যানের কাছে যায়
bc
। এটি পাঠ্য সংখ্যা নয়।2.1 < 2.10
এইভাবে ব্যর্থ হবে।