Suporte para analisar o JSON usando o sed necessário

1

No Home Assistant, é possível definir o estado de um switch executando um comando. Estou migrando para longe da minha antiga automação residencial e oferece uma maneira de obter o estado, infelizmente não para um switch, mas para todos eles. No fórum do HA, foi sugerido usar o sed para analisar a saída do json, mas não sou bom o suficiente para fazê-lo funcionar.

Eu recebo a seguinte saída:

{"status": "ok", "version": "3.381", "request": {"route": "/get-status" }, "response": {"preset":0,"time":"2018-03-08 09:45","switches":[{"id":0,"type":"switch","status":"off"},{"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":"off"},{"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"}]}}

e eu preciso do marcado em negrito. Em json eu faria algo como result.switches.id [0] .status e gostaria de poder fazer o mesmo com o sed. Eu consegui cortar a primeira parte (até comutadores), mas toda vez que eu tento obter algo como {"id": 0. * "Status" :( ". *")}. * Eu recebo tudo porque corresponde ao último} e não o primeiro que encontra.

Alguma sugestão?

    
por Jeroen Baker 08.03.2018 / 10:51

1 resposta

5

Sugestão: não analise o JSON com sed . Use algo como jq :

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

ou, se você quiser escolher o primeiro elemento da matriz em switches e não se importar com o% realid,

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

sed é bom para analisar texto orientado a linhas. JSON não vem em registros delimitados por nova linha, e sed não sabe sobre regras de cotação e entidades codificadas, etc. Para analisar corretamente um conjunto de dados estruturado como este (ou XML, YAML ou CSV em algumas circunstâncias), você deve use um analisador adequado.

Como um benefício adicional de usar jq neste exemplo, você obtém um código que é facilmente modificado para atender às suas necessidades, e que é igualmente fácil de modificar para suportar uma alteração no a estrutura de dados de entrada.

    
por 08.03.2018 / 10:57

Tags