支持使用 sed 解析 JSON 需要

1 sed json

在 Home Assistant 中,可以通过执行命令来设置开关的状态。我正在从我的旧家庭自动化迁移,它提供了一种获取状态的方法,不幸的是不是针对一个开关而是针对所有开关。在 HA 论坛中,有人建议使用 sed 来解析 json 输出,但我不够好,无法让它工作。

我得到以下输出:

{"status": "ok", "version": "3.381", "request": {"route": "/get-status" }, "response": {"preset":0,"time":" 2018-03-08 09:45","switches":[{"id":0,"type":"switch","status":"关闭"},{"id":1,"type":"switch","status":"off"},{"id":2,"type":"switch","status":"off"} ,{"id":3,"type":"dimmer","status":"off","dimlevel":0},{"id":4,"type":"switch","status": "off"},{"id":5,"type":"dimmer","status":"on","dimlevel":2},{"id":6,"type":"dimmer", "status":"off","dimlevel":0},{"id":7,"type":"switch","status":"off"},{"id":8,"type": "switch","status":"off"},{"id":9,"type":"switch","status":"off"},{"id":10,"type":"switch","status":"off"},{"id":11,"type":"switch","status" :"on"},{"id":16,"type":"switch","status":"off"},{"id":17,"type":"switch","status":"关闭"},{"id":18,"type":"virtual"},{"id":19,"type":"virtual"},{"id":20,"type":"switch" ,"status":"on"},{"id":21,"type":"switch","status":"off"},{"id":22,"type":"switch"," status":"off"},{"id":23,"type":"switch","status":"on"},{"id":24,"type":"switch","status":"off"},{"id":25,"type":"virtual"}],"uvmeters":[ ],"windmeters":[],"rainmeters":[{"id":2,"mm":0.7,"3h":0.7,"favorite":"no"}],"thermometers":[{" id":0,"te":19.1,"hu":49,"favorite":"no"},{"id":1,"te":18.5,"hu":48,"favorite":" no"}],"weatherdisplays":[], "energymeters": [], "energylinks": [{"id":0,"tariff":2,"s1":{"po":497,"dayTotal ":1.53,"po+":1379,"po+t":"09:11","po-":0,"po-t":"00:01"},"s2":{"po":0,"dayTotal":50.00,"po+":9,"po+t":"07:13","po-":0,"po-t":"00:01"} ,"aggregate":{"po":-314,"dayTotal":1.03,"po+":1363,"po+t":"07:26","po-":-1105,"po-t" :"08:39"},"used":{"po":183,"dayTotal":2.53,"po+":1463,"po+t":"07:26","po-":39, "po-t":"08:57"},"gas":{"lastHour":0.01,"dayTotal":1.50},"kwhindex":0.00}], "heatlinks": [], "kakusensors": [{"id":0,"status":null,"timestamp":"00:00"},{"id":1,"status":"no","timestamp":"09:21"} ,{"id":2,"status":null,"timestamp":"00:00"},{"id":3,"status":"no","timestamp":"09:20"},{"id":4, "status":null,"timestamp":"19:31"},{"id":5,"status":null,"timestamp":"00:00"},{"id":6,"status ":null,"timestamp":"00:00"},{"id":7,"status":null,"timestamp":"00:00"},{"id":8,"status": null,"timestamp":"00:00"},{"id":9,"status":null,"timestamp":"00:00"},{"id":10,"status":null, "timestamp":"00:00"},{"id":11,"status":null,"timestamp":"00:00"},{"id":12,"status":null,"timestamp":"18:51"}]}}

我需要用粗体标记的那个。在 json 中,我会做类似 result.switches.id[0].status 的事情,我希望能够用 sed 做同样的事情。我设法切断了第一部分(最多开关),但每次我尝试得到类似{"id":0.*"status":(".*")}.*我得到一切,因为它匹配最后} 而不是它遇到的第一个。

有什么建议?

Kus*_*nda 5

建议:不要用 .json 解析 JSON sed。使用类似的东西jq

$ jq -r '.response.switches[] | select(.id == 0).status' file.json
off
Run Code Online (Sandbox Code Playgroud)

或者,如果您想选择第一个数组元素switches并且不关心实际的id

$ jq -r '.response.switches[0].status' file.json
off
Run Code Online (Sandbox Code Playgroud)

sed适合解析面向行的文本。JSON 没有以换行符分隔的记录,sed也不知道引用规则和编码实体等。要正确解析这样的结构化数据集(或 XML,或 YAML,在某些情况下甚至是 CSV),您应该使用适当的解析器。

作为jq在这种情况下使用的额外好处,您可以获得一些易于修改以满足您的需要的代码,并且同样易于修改以支持输入数据结构的更改。