使用Bash与JQ实现JSON数组追加:首次创建及元素新增
How to Generate and Append to a Valid JSON File with JQ in Bash
我来帮你搞定这个问题——你现在的JQ命令之所以会输出一堆独立的JSON对象,是因为误用了-s参数加上传递了多个零散的JSON片段,完全偏离了你想要的嵌套结构和追加需求。下面是完整的解决方案,分首次创建和后续追加两种场景处理:
核心思路
我们需要先判断目标文件的状态,分情况处理:
- 如果文件不存在或为空:直接生成包含
ServiceData顶层对象、指定日期和初始ServiceInfo数组的合法JSON结构 - 如果文件已存在且非空:读取现有JSON,将新的服务信息对象安全追加到
ServiceData.ServiceInfo数组中
完整Bash脚本实现
#!/bin/bash # 定义你的业务变量(根据实际场景替换) TRANSACTION_ID_METRIC="tx-$(date +%s)" REALPBPODDEFNAME="payment-service" Cloudlintruntime="180ms" EXITCODE="success" totaltime="7s" TARGET_FILE="Test.json" # 指定日期(这里用当前时间,可替换为固定日期) SPECIFIED_DATE=$(date +%Y-%m-%dT%H:%M:%S) # 先构建要添加的单个服务信息对象 NEW_SERVICE_ENTRY=$(jq -n \ --arg tid "$TRANSACTION_ID_METRIC" \ --arg name "$REALPBPODDEFNAME" \ --arg lint "$Cloudlintruntime" \ --arg status "$EXITCODE" \ --arg build "$totaltime" \ '{transcationId: $tid, name: $name, lintruntime: $lint, status: $status, buildtime: $build}') # 判断文件是否存在且非空 if [ ! -s "$TARGET_FILE" ]; then # 首次执行:生成初始JSON结构 jq -n \ --arg date "$SPECIFIED_DATE" \ --argjson entry "$NEW_SERVICE_ENTRY" \ '{ServiceData: {date: $date, ServiceInfo: [$entry]}}' > "$TARGET_FILE" else # 后续执行:往ServiceInfo数组追加新元素(用临时文件避免损坏原文件) jq --argjson entry "$NEW_SERVICE_ENTRY" \ '.ServiceData.ServiceInfo += [$entry]' "$TARGET_FILE" > "$TARGET_FILE.tmp" && mv "$TARGET_FILE.tmp" "$TARGET_FILE" fi
关键修正点说明
避免生成零散JSON对象:
原来的命令传递了多个独立的{"key":"value"}片段,现在我们用jq -n结合--arg参数直接构建一个完整的服务信息对象,从根源上避免了多个JSON结构的问题。安全写入文件:
追加操作时先写入临时文件,确认执行成功后再替换原文件,防止JQ执行失败导致原文件损坏。严格匹配期望结构:
首次创建时直接生成你需要的嵌套结构,把新对象作为ServiceInfo数组的第一个元素;后续追加时用JQ的+=操作符,将新对象的数组([$entry])合并到原数组中,保证JSON格式始终合法。
测试验证
- 首次执行脚本后,
Test.json的内容会是:{ "ServiceData": { "date": "2024-05-20T15:45:00", "ServiceInfo": [ { "transcationId": "tx-1716209100", "name": "payment-service", "lintruntime": "180ms", "status": "success", "buildtime": "7s" } ] } } - 再次执行脚本,
ServiceInfo数组会新增一个元素,整体结构保持合法JSON格式。
内容的提问来源于stack exchange,提问作者XOR
相关产品推荐
相关产品推荐

