It's possible, but a silly amount of work. If you have GNU sort:
sort -V -r <STRINGS.txt
...will do exactly what you're asking for.
Now, if you really mean with no external tools, then you're getting into some trouble. BlastHardcheese on Freenode's #bash IRC channel has written the following quicksort algorithm in native bash, which I've modified for readability, to factor out the compare
function to be replacible, and to use Bash 4.3 namevars to be able to work with a configurable variable name (of course, this latter change means that a very new version of bash is required):
# this needs to be replaced for this particular case
compare(){
(( $1 >= $2 ))
}
swap(){
declare -n a=$1
local t
t=${a[$2]}
a[$2]=${a[$3]}
a[$3]=$t
}
partition(){
declare -n a=$1
local c p x
p=${a[$4]}
c=$2
swap "$1" "$3" "$4"
for((x=$2;x<$3;x++)); do
if ! compare "${a[x]}" "$p"; then
swap "$1" "$x" "$c"
((c++))
fi
done
swap "$1" "$2" "$c"
n=$c
}
quicksort(){
declare -n a=$1
(( "$2" >= "$3" )) && return
local i n
i=$((($2+$3)/2))
partition "$1" "$2" "$3" "$i"
quicksort "$1" "$2" "$((n-1))"
quicksort "$1" "$((n+1))" "$3"
}
...implement your own comparison function, and this is then adoptable.
To handle only the cases you've shown here:
# we want to return 0 if the first version is equal or later than the second
version_compare(){
local -a first second
# Let's start with trivial cases:
if [[ $1 = "$2" ]] || [[ $1 = "$2".* ]]; then : "$1 >= $2"; return 0; fi
IFS=. read -r -a first <<<"$1"
IFS=. read -r -a second <<<"$2"
local k
for k in "${!first[@]}"; do
local a=${first[$k]} b=${second[$k]}
: "Evaluating field $k ($a vs $b)"
if [[ ! $b ]]; then
# ie. first=1.1.1, second=1.1; though this should have been handled above
: "$1 >= $2"; return 0;
fi
if (( $b > $a )); then
: "$1 < $2"; return 1;
fi
done
: "$1 >= $2"; return 0;
}
compare() {
version_compare "$2" "$1" # reverse sort order
}
To do the file IO, assuming bash 4:
readarray -t versions <STRINGS.txt
quicksort versions 0 "$(( ${#versions[@]} - 1 ))"
printf '%s
' "${versions[@]}"
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…