更新:我已尝试提取我想要更新的路径,并在setpath(路径; getpath(路径))构造中使用相对于本地和返回对象(如下所示)的路径。我现在可以遍历$ paths数组并对本地json对象进行所需的更新。
使用下面的thermostats2.json文件和一个与thermostats2.json不同的ret.json:
{“location”:{“livingroom”:{“setpoints”:{“day”:“25000”}}}} #vs {“day”:“23000”}
我的脚本现在看起来像:
. as $obj |
# obtain location keys from $obj as they may have changed locally prior to $retobj being processed
($obj.location | keys? ) as $locs |
# setpoints are fixed in this code as ["day","night","away"]
["day","night","away"] as $setpoints |
[path($obj.location[($locs[])].setpoints[($setpoints[])])] as $paths |
reduce
range(0; $paths|length) as $i
(.; . | setpath($paths[$i];( $retobj[0] | getpath($paths[$i]))) ) | .
此时我不需要$ obj变量,但我还没有清理过它。如果您发现此方法存在问题或者这看起来是一个很好的解决方案,请发表评论。如果评论表明它应该是,我会回答这个问题。
我有一个json对象,它包含多个位置对象,每个位置对象包含几个设定点对象,以及其他数据。如果需要,将为此json对象提供远程应用程序,并将更新返回给设定点对象的值。我想更新本地json对象,而不是用返回的对象替换它。
我不想假设返回对象的位置键与本地对象的位置键相同,因为在修改远程对象时可能已经维护了本地对象。
我已经想出如何从本地文件中提取位置键,并创建一个包含我感兴趣的值更新的设定值键的数组。我还能够弄清楚如何将返回对象的更新值减少为数组。
我还没想到的是如何迭代位置和设定点以便更新本地json对象中的值。
我用:
调用jq# usage : jq --slurpfile retobj ret.json --from-file query.jq thermostats2.json
query.jq contains:
# use $obj as the local object to be updated with values returned in $retobj
# $retobj is not permitted to modify the structure of $obj
. as $obj |
# obtain location keys from $obj as they may have changed locally prior to $retobj being processed
($obj.location | keys? ) as $locs |
# setpoints are fixed in this code as ["day","night","away"]
["day","night","away"] as $setpoints |
reduce $retobj[0].location[($locs[])].setpoints[($setpoints[])] as $item
( []; . + [$item] )
| . as $vals |
$vals
thermostats2.json:
{ "mode":"Home",
"location": {
"livingroom": {
"scale":"Celcius",
"current": {
"valid":"YES",
"reading":"23000",
"time":"000000"
},
"previous": {
"reading":"23000",
"time":"000000"
},
"setpoints": {
"schedule": {
"weekday": {"day":"0600",
"night":"2100"
},
"weekend": {"day":"0630",
"night":"2200"
}
},
"active":"day",
"day":"23000",
"night":"15556",
"away":"12778"
}
},
"familyroom": {
"scale":"Celcius",
"current": {
"valid":"YES",
"reading":"23000",
"time":"000000"
},
"previous": {
"reading":"23000",
"time":"000000"
},
"setpoints": {
"schedule": {
"weekday": {"day":"0600",
"night":"2100"
},
"weekend": {"day":"0630",
"night":"2200"
}
},
"active":"day",
"day":"23000",
"night":"15556",
"away":"12778"
}
},
"28-000005e2fdef": {
"scale":"Celcius",
"current": {
"valid":"YES",
"reading":"23000",
"time":"000000"
},
"previous": {
"reading":"23000",
"time":"000000"
},
"setpoints": {
"schedule": {
"weekday": {"day":"0600",
"night":"2100"
},
"weekend": {"day":"0630",
"night":"2200"
}
},
"active":"day",
"day":"23000",
"night":"15556",
"away":"12778"
}
}
}
}
我找不到的是在$ obj中设置相同对象的值的任何方法,即有效:
$ obj [0] .location [($ locs [])]。setpoints [($ setpoints [])] = $ vals
据我所知,作为新手,我不太可能选择解决此类问题的首选方法。我也在努力在一些内置函数中使用过滤器范例,特别是foreach。
回顾我的目标,我希望:
通过从本地obj派生的位置键和过滤器中定义的设定点键在$ retobj中获取正确的对象值,并将本地对象中的相同路径设置为这些值。
答案 0 :(得分:0)
基于我对这个问题的理解,我相信使用--argfile而不是--slurpfile可以简化事情。
以下过滤器将根据thermostats2.json的内容调整$ retobj:
. as $in
| reduce ["location",
(.location | keys[]),
"setpoints",
["day","night","away"][]] as $path
( $retobj;
setpath( $path; ($in | getpath($path)) ) )
调用: jq --argfile retobj ret.json -f query.jq thermostats2.json