You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash3.2下如何排序数组使主元素在前并以树形结构打印

Bash 3.2 无关联数组场景下的数组排序与树形打印方案

问题约束

在Bash 3.2.54版本(无关联数组语法支持)中,对同时包含主元素、子元素的数组排序,要求:

  • 主元素格式为<主名>=<参数串>,必须排在其名下所有子元素之前
  • 子元素格式为<主名>%<命名空间>::<应用名>=<参数串>,同主名下的子元素按字符串自然顺序排列
  • 排序完成后按指定树形结构输出结果

原始测试数组定义如下:

myarr=()
myarr+=("demo1%myspace1::myapp1=param1#param2#param3")
myarr+=("demo1%myspace1::myapp2=param1#param2#param3")
myarr+=("demo1%myspace2::myapp1=param1#param2#param3")
myarr+=("demo1=param1#param2#param3")
myarr+=("demo2%myspace2::myapp1=param1#param2#param3")
myarr+=("demo2%myspace2::myapp2=param1#param2#param3")
myarr+=("demo2%myspace2::myapp3=param1#param2#param3")
myarr+=("demo2=param1#param2#param3")

预期排序后数组顺序:

"demo1=param1#param2#param3"
"demo1%myspace1::myapp1=param1#param2#param3"
"demo1%myspace1::myapp2=param1#param2#param3"
"demo1%myspace2::myapp1=param1#param2#param3"
"demo2=param1#param2#param3"
"demo2%myspace2::myapp1=param1#param2#param3"
"demo2%myspace2::myapp2=param1#param2#param3"
"demo2%myspace2::myapp3=param1#param2#param3"

预期树形打印效果:

demo1=param1#param2#param3
 |
 +-- demo1%myspace1::myapp1=param1#param2#param3
 +-- demo1%myspace1::myapp2=param1#param2#param3
 +-- demo1%myspace2::myapp1=param1#param2#param3

demo2=param1#param2#param3
 |
 +-- demo2%myspace2::myapp1=param1#param2#param3 
 +-- demo2%myspace2::myapp2=param1#param2#param3
 +-- demo2%myspace2::myapp3=param1#param2#param3

实现思路

不需要关联数组,借助系统自带sort命令,通过临时排序键转换即可完成排序,完全兼容Bash 3.2版本:

  • 提取每个元素=之前的前缀部分,判断元素类型:前缀不含%为主元素,含%为子元素
  • 为每个元素生成可排序的临时键:
    • 主元素临时键结构:<主名>\t0\t,同主名元素中排序优先级最高
    • 子元素临时键结构:<主名>\t1\t<完整前缀>,同主名子元素优先级低于主元素,且子元素之间按前缀自然序排列
  • 将临时键和原元素拼接后送入sort排序,排序完成后切掉临时键部分,即可得到目标顺序的数组
  • 遍历排序后数组,按规则拼接树形前缀打印即可

完整可运行代码

#!/bin/bash
# 原始数组初始化
myarr=()
myarr+=("demo1%myspace1::myapp1=param1#param2#param3")
myarr+=("demo1%myspace1::myapp2=param1#param2#param3")
myarr+=("demo1%myspace2::myapp1=param1#param2#param3")
myarr+=("demo1=param1#param2#param3")
myarr+=("demo2%myspace2::myapp1=param1#param2#param3")
myarr+=("demo2%myspace2::myapp2=param1#param2#param3")
myarr+=("demo2%myspace2::myapp3=param1#param2#param3")
myarr+=("demo2=param1#param2#param3")

# 数组排序
sorted_arr=()
while IFS= read -r line; do
  sorted_arr+=("${line#*$'\t'}")
done < <(
  for item in "${myarr[@]}"; do
    prefix="${item%%=*}"
    if [[ "$prefix" != *%* ]]; then
      # 主元素生成高优先级排序键
      printf "%s\t0\t\t%s\n" "$prefix" "$item"
    else
      # 子元素生成低优先级排序键
      main_name="${prefix%%%*}"
      printf "%s\t1\t%s\t%s\n" "$main_name" "$prefix" "$item"
    fi
  done | sort
)

# 树形结构打印
current_main=""
for item in "${sorted_arr[@]}"; do
  prefix="${item%%=*}"
  if [[ "$prefix" != *%* ]]; then
    [[ -n "$current_main" ]] && echo ""
    current_main="$prefix"
    echo "$item"
    echo " |"
  else
    echo " +-- $item"
  fi
done

执行上述脚本即可直接输出符合要求的结果,全程未使用Bash 4.0+才支持的关联数组语法,可在Bash 3.2.54环境下正常运行。

内容的提问来源于stack exchange,提问作者Mubin Icyer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 21:24:30