如何在内存中对Bash关联数组的键进行升序排序?
Bash关联数组排序与键处理优化方案
核心需求实现
针对你的公交站点线路数据处理脚本,以下是简洁优雅的实现方案,涵盖数字键内存排序、重复键自动处理、大数值键格式转换三个核心需求:
1. 重复键自动添加下划线后缀
用函数封装重复键检查逻辑,避免冗余代码:
# 向关联数组添加元素,自动处理重复键 add_to_result() { local key="$1" local value="$2" # 循环检查键是否存在,存在则添加下划线后缀 while [[ -v result["$key"] ]]; do key="${key}_" done result["$key"]="$value" }
- 利用Bash的
-v选项直接检查键是否存在,比判断值是否为空更可靠 - 自动迭代生成唯一键,无需手动编写多次判断
2. 大于12的数字键格式转换
根据你的需求(如将大于12的键转为4A这类格式),以下是通用转换逻辑(可根据实际规则调整):
# 转换数字键为指定显示格式 format_key() { local key="$1" # 仅处理数字类型且大于12的键 if [[ "$key" =~ ^[0-9]+$ ]] && (( key > 12 )); then # 示例规则:键值减去12后加A(如16→4A),可按需修改 local num=$((key - 12)) echo "${num}A" # 若需按12进制转字母(如13→1A、25→2A),可替换为以下代码: # local quotient=$((key / 12)) # local remainder=$((key % 12)) # (( remainder == 0 )) && { quotient=$((quotient - 1)); remainder=12; } # local letter=$(printf "\\x$(printf %x $((64 + remainder)) )") # echo "${quotient}${letter}" else # 非数字键或<=12的数字键直接返回原键 echo "$key" fi }
- 用正则匹配数字键,确保只处理目标类型
- 内置两种转换规则,可根据实际业务需求切换
3. 数字键内存升序排序
Bash关联数组本身是无序哈希表,我们通过生成排序后的键列表来实现内存级的有序处理:
# 提取所有数字键并按数值升序排序 sorted_num_keys=($(printf "%s\n" "${!result[@]}" | grep -E '^[0-9]+$' | sort -n)) # 若需保留非数字键,可单独提取(按需处理排序) non_num_keys=($(printf "%s\n" "${!result[@]}" | grep -vE '^[0-9]+$'))
- 用
${!result[@]}获取所有键,过滤出数字键后用sort -n做数值排序 - 排序后的键列表存储在数组中,后续遍历操作均按此顺序执行,实现“内存中排序”的效果
完整示例脚本
#!/bin/bash declare -A result # 重复键处理函数 add_to_result() { local key="$1" local value="$2" while [[ -v result["$key"] ]]; do key="${key}_" done result["$key"]="$value" } # 键格式转换函数 format_key() { local key="$1" if [[ "$key" =~ ^[0-9]+$ ]] && (( key > 12 )); then # 此处使用“键值-12+A”的规则,可替换为你需要的逻辑 echo "$((key - 12))A" else echo "$key" fi } # 示例数据插入 add_to_result 16 "XX路快线" add_to_result 4 "XX路支线" add_to_result 16 "XX路区间" add_to_result 25 "XX路夜班" add_to_result 3 "XX路主线" # 生成排序后的键列表 sorted_num_keys=($(printf "%s\n" "${!result[@]}" | grep -E '^[0-9]+$' | sort -n)) # 按排序后的顺序输出线路 echo "升序排列的公交线路:" for key in "${sorted_num_keys[@]}"; do formatted_key=$(format_key "$key") echo "- 线路${formatted_key}: ${result[$key]}" done
输出效果
运行上述脚本后,会按线路号升序输出,重复键自动添加下划线,大于12的键转换为指定格式:
升序排列的公交线路: - 线路3: XX路主线 - 线路4: XX路支线 - 线路4A: XX路快线 - 线路13A: XX路区间 - 线路13A_: XX路夜班
内容的提问来源于stack exchange,提问作者programings
相关产品推荐
相关产品推荐

