使用jq生成字典类型JSON数组时遇到内容异常问题
解决jq通过--arg传参生成JSON时端口值被覆盖的问题
这个问题我之前也碰到过!你遇到的端口全部变成最后一个值(83)的情况,核心原因是你在构建nodes数组元素时,一直在修改同一个初始对象(也就是<<<'{}'传入的空对象),后面的.port赋值会覆盖前面所有修改的结果。
问题出在哪?
看你写的这段逻辑:
.nodes=[ .ip=$value_a0 | .port=$value_b0, .ip=$value_a1 | .port=$value_b1, .ip=$value_a2 | .port=$value_b2 ]
每一组.ip=xxx | .port=xxx都是在同一个根对象上做修改:
- 第一次给根对象设
ip=1.1.1.1、port=81 - 第二次又在同一个根对象上把
ip改成2.2.2.2、port改成82 - 第三次再改成
ip=3.3.3.3、port=83
最后数组里的三个元素其实都是指向同一个对象的引用,自然显示的都是最后一次修改的结果。
正确的写法
要解决这个问题,你需要为每个节点独立创建新对象,而不是修改同一个上下文。直接用对象字面量{ip: ..., port: ...}的方式就能实现:
jq --arg value_a0 1.1.1.1 --arg value_b0 81 --arg value_a1 2.2.2.2 --arg value_b1 82 --arg value_a2 3.3.3.3 --arg value_b2 83 '. | .nodes=[ {ip: $value_a0, port: $value_b0}, {ip: $value_a1, port: $value_b1}, {ip: $value_a2, port: $value_b2} ]' <<<'{}'
运行结果验证
执行上面的命令后,你会得到符合预期的JSON:
{ "nodes": [ { "ip": "1.1.1.1", "port": "81" }, { "ip": "2.2.2.2", "port": "82" }, { "ip": "3.3.3.3", "port": "83" } ] }
额外小提示
如果需要传入的节点参数很多,逐个用--arg会很繁琐,可以考虑用--args批量传参,再通过索引来取值,比如:
jq -n --args '.nodes = [$ARGS.positions | range(0; length; 2) | {ip: .[.], port: .[.+1]}]' 1.1.1.1 81 2.2.2.2 82 3.3.3.3 83
这样只需要按ip port ip port的顺序传参,就能自动生成对应的节点数组啦。
内容的提问来源于stack exchange,提问作者dkalintsev
相关产品推荐
相关产品推荐

