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

如何在Bash 3.2(macOS)中将键值对字符串转为数组并按键取值

在Bash 3.2(macOS)中解析键值对字符串并实现按键取值

需求说明

有一批类似以下格式的字符串(来自JSON的result字段),需要解析后能直接通过键名获取对应值:

"result":"guid=guid1;forename=Jimmy Harry;surname=Jones;birthdate=20220201"
"result":"guid=guid2;forename=Sarah-Smith;middlename=;surname=Jones;birthdate=20220201"

目标是实现类似Java中按键取值的效果,而非遍历数组逐一匹配键名。

原代码问题分析

你提供的代码存在以下问题:

  • 数组拆分错误:array=($(echo "$result" | tr ';' '\n'))会把值中的空格也当作分隔符,导致Jimmy Harry被拆成两个数组元素,破坏键值对结构。
  • 遍历逻辑错误:for item in $array会按空白符展开数组,正确的遍历应该用for item in "${array[@]}"来保留每个键值对的完整性。
  • 条件判断错误:[[ $item == "forename*" ]]中的引号会让通配符*失效,应改为[[ $item == forename=* ]]才能匹配以forename=开头的键值对。
  • 变量引用错误:${item[counter]}是错误用法,item是单个字符串而非数组,直接使用$item即可。

解决方案

由于Bash 3.2不支持关联数组(Bash 4+才引入),可以通过以下两种方式模拟按键取值:

方案1:用函数实现按键查询

这种方法兼容性最好,支持键名含特殊字符、值含空格的场景:

# 定义按键取值函数
get_kv_value() {
    local target_key="$1"
    local kv_list="$2"
    # 拆分键值对为数组(保留值中的空格)
    IFS=';' read -ra kv_pairs <<< "$kv_list"
    # 遍历查找目标键
    for kv in "${kv_pairs[@]}"; do
        if [[ "$kv" == "$target_key="* ]]; then
            # 截取键名后的内容作为值返回
            echo "${kv#$target_key=}"
            return 0
        fi
    done
    # 未找到键时返回空字符串
    echo ""
    return 1
}

# 使用示例
# 提取JSON中的result值(假设已将result字段内容存入变量)
result_str="guid=guid1;forename=Jimmy Harry;surname=Jones;birthdate=20220201"

# 获取指定键的值
echo "forename: $(get_kv_value forename "$result_str")"
echo "guid: $(get_kv_value guid "$result_str")"
echo "birthdate: $(get_kv_value birthdate "$result_str")"

方案2:动态赋值为变量(键名需符合变量规则)

如果键名是合法的Bash变量名(无空格、特殊字符),可以直接将键值对转为变量,实现直接通过变量名取值:

result_str="guid=guid1;forename=Jimmy Harry;surname=Jones;birthdate=20220201"

# 拆分键值对为数组
IFS=';' read -ra kv_pairs <<< "$result_str"

# 遍历赋值变量
for kv in "${kv_pairs[@]}"; do
    # 跳过无效的键值对(无=的情况)
    if [[ "$kv" == *=* ]]; then
        # 拆分键和值
        key="${kv%%=*}"
        value="${kv#*=}"
        # 动态赋值变量(注意:如果值含特殊字符需额外处理)
        eval "$key='$value'"
    fi
done

# 直接使用变量取值
echo "forename: $forename"
echo "guid: $guid"
echo "birthdate: $birthdate"

关键知识点

  • IFS=';' read -ra kv_pairs <<< "$str":用分号作为分隔符拆分字符串到数组,-r防止反斜杠被转义,-a指定赋值到数组,能保留值中的空格。
  • ${kv#$target_key=}:从字符串开头删除匹配$target_key=的部分,得到对应的值。
  • ${kv%%=*}:从字符串末尾向前匹配第一个=,截取左边的键名;${kv#*=}从开头匹配第一个=,截取右边的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:01:18