如何用jq将过滤修改后的JSON数组追加到JSON文件?
JSON数组过滤修改并追加到文件的问题与解决方案
问题描述
我有一个存储JSON对象数组的文件full_meta.json,内容如下:
[{"product_id":"xxx","name":"yyy","qty":111},{"product_id":"881","name":"aaa","qty":200}]
需要过滤其中的子集并修改后,追加到初始为空数组的sub_meta.json文件中。
尝试了以下bash命令:
- 过滤并修改ID:
d=$(jq '[.[] | select(.product_id == "881")] | map(.product_id ="881-new")' full_meta.json)
- 追加到目标文件:
jq --argjson tmp "$d" '.+=$tmp' sub_meta.json
但执行时出现错误:
parse error: Invalid numeric literal at line 1, column 6
错误原因
错误出在--argjson的使用上:默认情况下jq输出的是带换行的格式化JSON,保存到变量$d后包含换行符,而--argjson要求传入的必须是单行、无多余空白的合法JSON字符串,换行符会导致JSON解析失败。
最佳实现方法
方法一:合并操作,避免中间变量(推荐)
直接用一条jq命令完成所有操作,无需保存中间结果到变量,更简洁可靠:
# 先确保目标文件是合法的空数组(首次执行时需要) echo "[]" > sub_meta.json # 执行过滤、修改、追加操作 jq --slurpfile src full_meta.json '. += ($src[0] | .[] | select(.product_id == "881") | .product_id = "881-new") | [.[]]' sub_meta.json > tmp.json && mv tmp.json sub_meta.json
说明:
--slurpfile src full_meta.json:将full_meta.json的内容读入数组变量$src$src[0] | .[] | select(...) | .product_id = ...:从源数组中筛选目标元素并修改ID. += (...):把处理后的元素追加到目标数组[.[]]:确保结果始终是数组格式(避免筛选出单个元素时输出非数组)- 用临时文件
tmp.json中转后覆盖原文件,防止直接写入导致的文件清空问题
方法二:正确处理中间变量
如果必须使用中间变量,需要让jq输出单行紧凑JSON:
# 生成单行JSON并保存到变量 d=$(jq -c '[.[] | select(.product_id == "881")] | map(.product_id ="881-new")' full_meta.json) # 追加到目标文件 jq --argjson tmp "$d" '. += $tmp' sub_meta.json > tmp.json && mv tmp.json sub_meta.json
说明:
-c参数让jq输出紧凑的单行JSON,消除换行符,确保--argjson能正常解析- 同样用临时文件中转来避免数据丢失
内容的提问来源于stack exchange,提问作者Udhayha Karthik
相关产品推荐
相关产品推荐

