如何使用JQ命令在JSON指定键后追加插入新对象
问题背景
现有如下JSON文件:
{ "ver" : "v2.0", "date" : "11 Jul 2022 21:28 WIB", "disk" : {}, "network" : {}, "bench" : {} }
需要在date键对应条目之后追加hw对象,最终得到的文件结构如下:
{ "ver" : "v2.0", "date" : "11 Jul 2022 21:28 WIB", "hw": { "cpu": "intel" }, "disk" : {}, "network" : {}, "bench" : {} }
尝试参考命令jq -S '. |= . + {"hw":{ "cpu" : "intel" }}'时,该命令仅会把新内容追加到对象末尾,修改命令后执行出现报错:jq: error (at main.json:7): Cannot index object with number,需要可实现指定位置插入键值对的正确JQ查询语句。
正确实现方法
RFC标准中JSON对象的键顺序不做强制要求,但jq 1.6+版本支持通过键值对条目的转换手动控制输出顺序,可直接使用以下命令:
jq 'to_entries | map(if .key == "date" then ., {key:"hw", value:{cpu:"intel"}} else . end) | from_entries' main.json
命令逻辑拆解:
to_entries:将原JSON对象转换为有序的键值对数组,每个数组元素格式为{"key": 键名, "value": 键对应值},完整保留原文件的键排列顺序map():遍历上述键值对数组,匹配到键名为date的条目时,先保留原有date条目,紧接着插入新的hw键值对,其余条目顺序保持不变from_entries:将处理完成的键值对数组重新转换回JSON对象结构
如果需要直接修改原文件,可搭配sponge工具(需先安装moreutils包)执行:
jq 'to_entries | map(if .key == "date" then ., {key:"hw", value:{cpu:"intel"}} else . end) | from_entries' main.json | sponge main.json
之前命令的问题说明
- 之前使用的
. + {新对象}属于对象合并操作,jq默认会将合并新增的键放在对象的最末尾,因此无法插入到date键之后 - 出现
Cannot index object with number报错,是因为修改命令时尝试用数字下标直接索引JSON对象,JSON对象不是数组类型,不支持数字下标取值。
内容的提问来源于stack exchange,提问作者Liso
相关产品推荐
相关产品推荐

