需要支持使用 sed 解析 JSON

需要支持使用 sed 解析 JSON

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

我得到以下输出:

{“状态”:“确定”,“版本”:“3.381”,“请求”:{“路线”:“/ get-status”},“响应”:{“预设”:0,“时间”:“ 2018-03-08 09:45","开关":[{"id":0,"类型":"开关","状态":"离开"},{"id":1,"type":"switch","status":"off"},{"id":2,"type":"switch","status":"off"} ,{"id":3,"type":"调光器","status":"off","dimlevel":0},{"id":4,"type":"switch","status": "关"},{"id":5,"type":"调光器","status":"开","dimlevel":2},{"id":6,"type":"调光器", “状态”:“关闭”,“dimlevel”:0},{“id”:7,“类型”:“开关”,“状态”:“关闭”},{“id”:8,“类型”: "开关","状态":"关闭"},{"id":9,"类型":"开关","状态":"关闭"},{"id":10,"类型":"开关","status":"关"},{"id":11,"type":"开关","status":"开"},{"id":16,"type":"开关", "status":"关闭"},{"id":17,"type":"switch","status":"关闭"},{"id":18,"type":"虚拟"},{ "id":19,"type":"虚拟"},{"id":20,"type":"开关","status":"on"},{"id":21,"type": "开关","状态":"关闭"},{"id":22,"类型":"开关","状态":"关闭"},{"id":23,"类型":"开关","status":"开"},{"id":24,"type":"开关","status":"关"},{"id":25,"type":"虚拟"} ],"uvmeters":[],"windmeters":[],"rainmeters":[{"id":2,"mm":0.7,"3h":0.7,"favorite":"no"}], "温度计":[{"id":0,"te":19.1,"hu":49,"最喜欢的":"否"},{"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"},"聚合":{"po":-314,"日总计":1.03,"po+":1363,"po+t":"07:26","po-":-1105,"po -t":"08:39"},"已使用":{"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 ,"状态":"否","时间戳":"09:21"},{"id":2,"状态":null,"时间戳":"00:00"},{"id":3 ,"状态":"否","时间戳":"09:20"},{"id":4,"状态":null,"时间戳":"19:31"},{"id":5 ,"状态":null,"时间戳":"00:00"},{"id":6,"状态":null,"时间戳":"00:00"},{"id":7,"状态":null,"时间戳":"00:00"},{"id":8,"状态":null,"时间戳":"00:00"},{"id":9,"状态" :null,"时间戳":"00:00"},{"id":10,"状态":null,"时间戳":"00:00"},{"id":11,"状态":null ,"timestamp":"00:00"},{"id":12,"status":null,"timestamp":"18:51"}]}}

我需要以粗体标记的那个。在 json 中,我会执行类似 result.switches.id[0].status 的操作,并且我希望能够使用 sed 执行相同的操作。我设法切断第一部分(直到开关),但每次我尝试得到类似的东西{"id":0.*"状态":(".*")}.*我得到了一切,因为它匹配最后一个 } 而不是它遇到的第一个。

有什么建议么?

答案1

建议:不要用sed.使用类似的东西jq来代替:

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

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

$ jq -r '.response.switches[0].status' file.json
off

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

作为在本例中使用的一个额外好处jq,您会得到一些代码:容易地修改以满足您的需求,并且同样可以轻松修改以支持输入数据结构的更改。

相关内容