Json jq试图迭代两组值
更新:我尝试过提取我想要更新的路径,并在setpath(path;getpath(path))构造中使用这些相对于本地和返回对象(如下所示)的路径。现在,我可以遍历$paths数组,并对本地json对象进行所需的更新 使用下面的thermostats2.json文件和ret.json,该ret.json与thermostats2.json仅在以下方面不同: {“地点”:{“起居室”:{“设定点”:{“日期”:“25000”}}}}}}与{“日期”:“23000”} 我的脚本现在看起来像:Json jq试图迭代两组值,json,jq,Json,Jq,更新:我尝试过提取我想要更新的路径,并在setpath(path;getpath(path))构造中使用这些相对于本地和返回对象(如下所示)的路径。现在,我可以遍历$paths数组,并对本地json对象进行所需的更新 使用下面的thermostats2.json文件和ret.json,该ret.json与thermostats2.json仅在以下方面不同: {“地点”:{“起居室”:{“设定点”:{“日期”:“25000”}}}}}}与{“日期”:“23000”} 我的脚本现在看起来像: . a
. 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
恒温器2.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"
}
}
}
}
. as $in
| reduce ["location",
(.location | keys[]),
"setpoints",
["day","night","away"][]] as $path
( $retobj;
setpath( $path; ($in | getpath($path)) ) )
我找不到任何方法来设置$obj中相同对象的值,即有效地:
$obj[0]。位置[($locs[])]。设定点[($setpoints[])]=$VAL
我明白,作为一个新手,我不太可能选择解决这类问题的首选方法。我还在努力在一些内置函数中采用过滤器范例,尤其是foreach
为了概括我的目标,我希望:
通过从本地obj派生的位置键和过滤器中定义的设定点键,在$retobj中获取正确的对象值,并将本地对象中的路径设置为这些值。基于我对这个问题的理解,我相信使用--argfile而不是--slurpfile可以简化事情 以下过滤器将根据thermostats2.json的内容调整$retobj:
{ "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"
}
}
}
}
. 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.json1。ret.json在哪里?2.是否有可能将示例筛选到更接近最小的值,以便您也可以轻松地显示预期的输出?请看,目前ret.json与thermostats2.json完全相同,除了{location:{livingroom:{setpoints:{day:25000}}}}}我将尝试使用path()getpath(path)和setpath(path;value)探索一种方法后,使用一组更简单的对象。我已经成功地构建了一个路径数组,用于更新该数组的元素并将其应用于obj和retobj。我将编辑我的第一个问题。我有更多的信息。谢谢。除了改变基于$retobj修改thermostats2.json内容的目标之外,您的回答证实了我昨晚探索的方法,此外,还揭示了构建$path的另一种符号,而我对此理解缓慢。我还将回顾--argfile与--slurpfile,以了解何时使用它们。虽然我只在jq工作了几天,但表达的简洁给我留下了深刻的印象。哇,不过这是一个多么好的学习曲线啊!只是查看了--argfile的文档:“不要使用.use--slurpfile代替。”--argfile比--slurpfile存在的时间更长,在本例中,如果使用--slurpfile,那么您必须记住“清除”刚刚“清除”的内容,这会使事情变得更简单。