如何用Shell脚本与jq命令合并含共同timestamp键的对象数组?
使用Shell脚本与jq合并JSON数据集
我拥有两个JSON数据集:
data1='[ { "bookings": 2984, "timestamp": 1675854900 }, { "bookings": 2967, "timestamp": 1675855200 } ]' data2='[ { "errors": 51, "timestamp": 1675854900 }, { "errors": 90, "timestamp": 1675855200 } ]'
期望合并后得到如下输出:
combined='[ { "errors": 51, "bookings": 2984, "timestamp": 1675854900 }, { "errors": 90, "bookings": 2967, "timestamp": 1675855200 } ]'
实现方案
完全可以通过Shell脚本结合jq命令实现,由于已知timestamp字段在两个数据集中取值一致且顺序相同,我们可以利用jq的数组配对与对象合并功能完成需求。
方法1:使用transpose函数
data1='[ { "bookings": 2984, "timestamp": 1675854900 }, { "bookings": 2967, "timestamp": 1675855200 } ]' data2='[ { "errors": 51, "timestamp": 1675854900 }, { "errors": 90, "timestamp": 1675855200 } ]' # 执行合并操作 combined=$(jq -n --argjson d1 "$data1" --argjson d2 "$data2" '[$d1[], $d2[]] | transpose | map(add)') # 输出结果 echo "combined='$combined'"
方法2:使用zip函数(jq 1.6及以上版本支持)
zip函数可以更直观地将两个数组的对应元素配对,写法更简洁:
combined=$(jq -n --argjson d1 "$data1" --argjson d2 "$data2" '$d1 | zip($d2) | map(add)') echo "combined='$combined'"
命令说明
--argjson:将Shell变量中的JSON字符串作为JSON类型参数传入jq,避免字符串转义问题transpose/zip:将两个数组的对应元素配对成子数组,确保相同timestamp的对象被放在一起map(add):遍历每一对对象,执行合并操作,自动合并键值对(相同键timestamp因值一致,合并后无影响)
注:jq输出的是标准JSON格式(所有键均带双引号),这符合JSON规范;你提供的期望输出中bookings未加双引号属于JavaScript对象写法,若需这种格式,可额外使用jq的--raw-output配合字符串格式化,但不建议偏离标准JSON规范。
内容的提问来源于stack exchange,提问作者Arpit Agarwal
相关产品推荐
相关产品推荐

