Json jq试图迭代两组值

Json jq试图迭代两组值,json,jq,Json,Jq,更新:我尝试过提取我想要更新的路径,并在setpath(path;getpath(path))构造中使用这些相对于本地和返回对象(如下所示)的路径。现在,我可以遍历$paths数组,并对本地json对象进行所需的更新 使用下面的thermostats2.json文件和ret.json,该ret.json与thermostats2.json仅在以下方面不同: {“地点”:{“起居室”:{“设定点”:{“日期”:“25000”}}}}}}与{“日期”:“23000”} 我的脚本现在看起来像: . a

更新:我尝试过提取我想要更新的路径,并在setpath(path;getpath(path))构造中使用这些相对于本地和返回对象(如下所示)的路径。现在,我可以遍历$paths数组,并对本地json对象进行所需的更新

使用下面的thermostats2.json文件和ret.json,该ret.json与thermostats2.json仅在以下方面不同:

{“地点”:{“起居室”:{“设定点”:{“日期”:“25000”}}}}}}与{“日期”:“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
恒温器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.json

1。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,那么您必须记住“清除”刚刚“清除”的内容,这会使事情变得更简单。