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

如何通过Bash脚本从多个数组生成指定结构的JSON文件

Bash数组转指定结构JSON的解决方案

问题场景

你有以下关联的Bash数组(或字符串形式的数组):

# 作为JSON顶层键的数组(原字符串形式转成数组更可靠)
arr1=(200 300 400)
# 对应feature1的值
arr2=(1000 1001 1002)
# 对应feature2的文件路径(来自你的工作流生成)
arr3=("/path/to/1000.log" "/path/to/1001.log" "/path/to/1002.log")

需要生成嵌套结构的JSON,将arr1的元素作为顶层键,arr2、arr3的对应元素作为子对象的feature1、feature2值。之前直接传递整个数组给jq的方式会把数组当成单个字符串,无法生成预期的多键结构。


基础需求(仅两个数组)

方法1:Bash循环拼接JSON片段

适合逻辑简单、不想依赖复杂jq语法的场景:

arr1=(200 300 400)
arr2=(1000 1001 1002)

# 初始化JSON框架
json_output="{"

# 遍历数组索引,逐个生成键值对
for idx in "${!arr1[@]}"; do
    key="${arr1[$idx]}"
    feature1_val="${arr2[$idx]}"
    # 非第一个元素前加逗号分隔
    if [ "$idx" -gt 0 ]; then
        json_output="$json_output,"
    fi
    json_output="$json_output\"$key\": {\"feature1\": $feature1_val}"
done

json_output="$json_output}"

# 用jq格式化输出(可选,让JSON更美观)
echo "$json_output" | jq .

方法2:jq数组配对(更简洁)

利用jq的数组处理功能,先将Bash数组转为jq可识别的JSON数组,再配对生成目标结构:

arr1=(200 300 400)
arr2=(1000 1001 1002)

jq -n --argjson keys "$(printf '%s\n' "${arr1[@]}" | jq -R . | jq -s .)" \
      --argjson feature1_vals "$(printf '%s\n' "${arr2[@]}" | jq -nR . | jq -s .)" \
      '[$keys, $feature1_vals] | transpose | map({(.[0]): {"feature1": .[1] | tonumber}}) | add'
  • printf '%s\n' "${arr1[@]}":将Bash数组元素逐行输出
  • jq -R .:将每行内容转为JSON字符串
  • jq -s .:将所有字符串转为JSON数组
  • transpose:将两个数组按索引配对,生成[[key1, val1], [key2, val2], ...]的结构
  • map:将每一组配对转为目标键值对象
  • add:将所有对象合并为一个顶层JSON对象

补充需求(三个数组,含feature2)

基于你的工作流生成的arr1、arr2、arr3,用jq实现更高效:

# 先将原字符串形式的arr1转为Bash数组(你的工作流中arr1是字符串)
arr1=($arr1)

jq -n --argjson keys "$(printf '%s\n' "${arr1[@]}" | jq -R . | jq -s .)" \
      --argjson feature1_vals "$(printf '%s\n' "${arr2[@]}" | jq -nR . | jq -s .)" \
      --argjson feature2_vals "$(printf '%s\n' "${arr3[@]}" | jq -R . | jq -s .)" \
      '[$keys, $feature1_vals, $feature2_vals] | transpose | map({(.[0]): {"feature1": .[1] | tonumber, "feature2": .[2]}}) | add'
  • tonumber:将feature1的字符串值转为数字类型(符合JSON格式要求)
  • 若arr3的路径包含特殊字符(如空格),jq会自动处理转义,无需手动处理

如果偏好Bash循环方式,可参考基础需求的循环逻辑扩展:

arr1=($arr1)
json_output="{"

for idx in "${!arr1[@]}"; do
    key="${arr1[$idx]}"
    f1="${arr2[$idx]}"
    f2="${arr3[$idx]}"
    if [ "$idx" -gt 0 ]; then
        json_output="$json_output,"
    fi
    json_output="$json_output\"$key\": {\"feature1\": $f1, \"feature2\": \"$f2\"}"
done

json_output="$json_output}"
echo "$json_output" | jq .

为什么之前的方法失效

你之前用--arg arg1 "${arr1[*]}"传递数组时,${arr1[*]}会把数组元素拼接成一个空格分隔的字符串(如"200 300 400"),jq只会将其作为单个字符串处理,因此生成的是一个键为该字符串的单一条目,而非多个独立键值对。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 21:39:36