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

如何在Bash中高效将API返回的JSON数组转为可交互菜单?

在Bash中解析JSON生成选择菜单并处理用户输入

我从API获取了如下JSON数组数据:

[{"name":"***.com","id":"***-0a5864441f49","type":"NATIVE"},{"name":"***.de","id":"***-0a5864441f49","type":"NATIVE"},{"name":"***.com","id":"***-0a5864440f67","type":"NATIVE"},{"name":"***.de","id":"***-0a5864441314","type":"NATIVE"},{"name":"***.com","id":"***-0a586444968b","type":"NATIVE"},{"name":"***.de","id":"***-0a5864441314","type":"NATIVE"},{"name":"***.de","id":"***-0a5864441f49","type":"NATIVE"},{"name":"***.de","id":"***-0a5864441f49","type":"NATIVE"},{"name":"***.de","id":"***-0a58644406ac","type":"NATIVE"},{"name":"***.de","id":"***-0a58644435f4","type":"NATIVE"}]

希望将其转换为如下格式的选择菜单:

Choose one:
1. ***.com ***-0a5864441f49
2. ***.de ***-0a5864441f49
and so on...

之后还需进一步使用用户的选择输入。请问在Bash中实现该需求的最高效方法是什么?我曾考虑使用数组,但认为用},{作为IFS分隔符不可行,尝试后也未成功。


最佳解决方案:使用jq解析JSON(高效且健壮)

手动用IFS分割JSON字符串非常不可靠,因为JSON的结构可能存在空格、转义字符等变化,容易出错。jq是Bash中处理JSON的标准工具,能精准解析结构,是最高效的方案。

完整实现代码

#!/bin/bash

# 假设API返回的JSON数据已存入变量json_data
json_data='[{"name":"***.com","id":"***-0a5864441f49","type":"NATIVE"},{"name":"***.de","id":"***-0a5864441f49","type":"NATIVE"},{"name":"***.com","id":"***-0a5864440f67","type":"NATIVE"},{"name":"***.de","id":"***-0a5864441314","type":"NATIVE"},{"name":"***.com","id":"***-0a586444968b","type":"NATIVE"},{"name":"***.de","id":"***-0a5864441314","type":"NATIVE"},{"name":"***.de","id":"***-0a5864441f49","type":"NATIVE"},{"name":"***.de","id":"***-0a5864441f49","type":"NATIVE"},{"name":"***.de","id":"***-0a58644406ac","type":"NATIVE"},{"name":"***.de","id":"***-0a58644435f4","type":"NATIVE"}]'

# 1. 用jq解析JSON,生成带序号的菜单,同时将每个条目存入数组
mapfile -t items < <(jq -r 'to_entries[] | "\(.key+1). \(.value.name) \(.value.id)"' <<< "$json_data")

# 2. 显示选择菜单
echo "Choose one:"
printf '%s\n' "${items[@]}"

# 3. 读取用户输入
read -p "Enter the number of your choice: " choice

# 4. 验证输入并提取对应数据
if [[ "$choice" =~ ^[0-9]+$ && "$choice" -ge 1 && "$choice" -le "${#items[@]}" ]]; then
    selected_item="${items[$((choice-1))]}"
    # 提取name和id(也可以直接用jq根据索引获取原始数据)
    selected_name=$(jq -r ".[$((choice-1))].name" <<< "$json_data")
    selected_id=$(jq -r ".[$((choice-1))].id" <<< "$json_data")
    echo "You selected: $selected_name ($selected_id)"
    # 这里可以添加后续处理逻辑
else
    echo "Invalid choice!"
    exit 1
fi

关键步骤说明

  1. mapfile+jq生成数组:

    • jq -r 'to_entries[] | "\(.key+1). \(.value.name) \(.value.id)"':将JSON数组转为键值对,键是索引(从0开始),加1后作为菜单序号,拼接name和id生成菜单条目。
    • mapfile -t items:将jq输出的每一行存入数组items,-t用于去掉换行符。
  2. 处理用户选择:

    • 验证输入是否为有效数字,且在菜单序号范围内。
    • 可以直接通过数组索引获取菜单文本,也可以再次用jq根据索引从原始JSON中提取完整的name/id数据,适合后续业务逻辑使用。

为什么不推荐手动分割JSON?

用IFS="},{分割字符串的方法非常脆弱:

  • JSON中可能存在嵌套结构、空格、转义引号等,会导致分割结果混乱。
  • 如果API返回的JSON格式稍有变化(比如新增字段、调整空格),脚本就会失效。
  • jq是专门为JSON设计的工具,处理效率和可靠性远高于手动字符串操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 12:50:59