这是可能的,但工作量却很愚蠢。如果您使用GNU排序:
sort -V -r <STRINGS.txt
…将完全按照您的要求进行。
现在,如果您 真的 没有任何外部工具,那么您将遇到麻烦。Freenode的#bash
IRC频道上的BlastHardcheese已在本机bash中编写了以下quicksort算法,出于可读性的考虑,我对其进行了修改,以使该
compare函数具有可替换性,并使用Bash
4.3 namevars使其能够与可配置变量名一起使用(当然,后面的更改意味着需要一个非常新的bash版本):
# this needs to be replaced for this particular casecompare(){ (( $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"}…实现自己的比较功能,然后就可以采用了。
要仅处理您在此处显示的情况:
# we want to return 0 if the first version is equal or later than the secondversion_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}假设bash 4,执行文件IO:
readarray -t versions <STRINGS.txtquicksort versions 0 "$(( ${#versions[@]} - 1 ))"printf '%sn' "${versions[@]}"


