Arrays 基于预定义列表排序

Arrays 基于预定义列表排序,arrays,bash,sed,Arrays,Bash,Sed,如何根据我在Bash中预定义的列表对数组顺序进行排序 我预先定义的列表 fixed=(john doe mary ben) 我希望它更改的数组 changetimetotime=(ben-5 doe-1 john-1) 我需要满足的标准很少 我需要的bash代码 changetimetotime数组的数量不必有3个,有时是1个值,但最大值是4个值 固定数组只提供名称,changetimetotime也提供版本号 满足这两个条件后,阵列将更改为以下 changetimetotime=(john

如何根据我在Bash中预定义的列表对数组顺序进行排序

我预先定义的列表

fixed=(john doe mary ben)
我希望它更改的数组

changetimetotime=(ben-5 doe-1 john-1)
我需要满足的标准很少

我需要的bash代码

  • changetimetotime数组的数量不必有3个,有时是1个值,但最大值是4个值

  • 固定数组只提供名称,changetimetotime也提供版本号

  • 满足这两个条件后,阵列将更改为以下

    changetimetotime=(john-1 doe-1 ben-5) 
    
    我需要访问循环外部的changetimetotime数组


    如果元素总是包含在使用稀疏数组的预定义集合中,请提供帮助。

    fixed=(john doe mary ben)
    
    # to fill an associative array from fixed array
    # if supported (bash >4) otherwise use a decoding function
    declare -A hash=()
    for i in "${!fixed[@]}"; do hash[${fixed[i]}]=$i; done
    
    changetimetotime=(ben-5 doe-1 john-1)
    newchangetimetotime=()
    for element in "${changetimetotime[@]}"; do
        index=${hash[${element%%-*}]}
        newchangetimetotime[index]=$element
    done
    
    echo "${newchangetimetotime[@]}"
    
    # overwrite array reindexing keys
    changetimetotime=("${newchangetimetotime[@]}")
    
    否则,请使用快速排序处理一般情况

    # an associative array to decode names to an int
    declare -A hash=([john]="1" [doe]="2" [mary]="3" [ben]="4")
    
    # or to fill from fixed array
    # declare -A hash=()
    # for i in "${!fixed[@]}"; do hash[${fixed[i]}]=$i; done
    
    # function used to compare two elements
    # exit status is success (0) if first is less or equal to second
    is_ordered () {
        # if string after name can contain many '-', % may be changed to %% to remove logest matched suffix
        # extract names from elements
        local k1=${1%-*} k2=${2%-*}
        local v1=${hash[$k1]} v2=${hash[$k2]}
        (($v1<=$v2))
    }
    
    # recursive quick sort
    qsort () {
        local l=() g=() p=$1
        r=()
        shift || return
        for i; do
            if is_ordered "$i" "$p"; then
                l+=("$i")
            else
                g+=("$i")
            fi
        done
    
        qsort "${g[@]}"
        g=("${r[@]}")
        qsort "${l[@]}"
        l=("${r[@]}")
    
        r=("${l[@]}" "$p" "${g[@]}")
    }
    
    qsort "${changetimetotime[@]}"
    changetimetotime=("${r[@]}")
    
    #将名称解码为整数的关联数组
    声明-A散列=([john]=“1”[doe]=“2”[mary]=“3”[ben]=“4”)
    #或从固定数组填充
    #声明-A散列=()
    #对于“${!fixed[@]}”中的i;dohash[${fixed[i]}]=$i;完成
    #用于比较两个元素的函数
    #如果第一个小于或等于第二个,则退出状态为成功(0)
    是有序的(){
    #如果名称后的字符串可以包含许多“-”,则%可以更改为%%,以删除logest匹配的后缀
    #从元素中提取名称
    局部k1=${1%-*}k2=${2%-*}
    本地v1=${hash[$k1]}v2=${hash[$k2]}
    ($v1)