Eu tenho bin procurando uma solução para a minha pergunta, mas não encontrei uma ou melhor, disse que não a obtive com o que encontrei. Então, vamos falar sobre o que é o meu problema. Estou usando um software de controle doméstico inteligente em um Raspberry Pi e, como descobri neste final de semana usando o pilight-receive, posso pegar os dados do meu sensor de temperatura externo. A saída do pilight-receive é assim:
{
"message": {
"id": 4095,
"temperature": 409.5
},
"origin": "receiver",
"protocol": "alecto_wsd17",
"uuid": "0000-b8-27-eb-0f3db7",
"repeats": 3
}
{
"message": {
"id": 1490,
"temperature": 25.1,
"humidity": 40.0,
"battery": 1
},
"origin": "receiver",
"protocol": "alecto_ws1700",
"uuid": "0000-b8-27-eb-0f3db7",
"repeats": 3
}
{
"message": {
"id": 2039,
"temperature": 409.5
},
"origin": "receiver",
"protocol": "alecto_wsd17",
"uuid": "0000-b8-27-eb-0f3db7",
"repeats": 4
}
Agora, minha pergunta é: como diabos posso extrair a temperatura e a umidade de onde o id é 1490. E como você recomendaria que eu fizesse isso com freqüência? Por um trabalho cron que é executado a cada 10 minutos, cria uma saída do pilight-receive, extrai os dados da saída e os envia para a API do Smart Home Control.
Alguém tendo uma ideia - muito obrigado
fonte
awk
esed
desde que a saída JSON retenha a formatação mostrada aqui, o que não é necessário - espaço em branco não importa para JSON. Por exemplo, esteawk
comando:awk '/temperature|humidity/ {print $2}'
está próximo.ksh93
json parsing está embutido emread
.Respostas:
Você pode usar
jq
para processar arquivos json no shell.Por exemplo, salvei seu arquivo json de exemplo
raul.json
e executei:O jq está disponível pré-empacotado para a maioria das distribuições linux.
Provavelmente existe uma maneira de fazer isso por
jq
si só, mas a maneira mais simples que encontrei para obter os dois valores desejados em uma linha é usarxargs
. Por exemplo:ou, se você desejar percorrer cada
.message.id
instância, podemos adicionar.message.id
à saída e usarxargs -n 3
como sabemos que haverá três campos (id, temperatura, umidade):Você pode pós-processar essa saída com awk ou o que quer que seja.
Por fim, python e perl têm excelentes bibliotecas para analisar e manipular dados json. Assim como várias outras línguas, incluindo php e java.
fonte
jq 'select(.message.id == 1490) | .message.temperature, .message.humidity' raul.json
{ read temp; read hum; } < <(jq ...)
grep
. Pode não funcionar para algumas versões específicas dogrep
, mas é mais direto do quejq
neste cenário, embora tenhajq
sido projetado especificamente para analisar o JSON. Deijq
uma resposta positiva, apesar de tudo. É realmente uma ferramenta para o trabalho, mas às vezes você pode simplesmente remover grampos com os dedos, em vez de procurar um removedor de grampos.jq
é um desses para scripts de shell. outros idiomas têm bibliotecas de análise de json.jq
isso?jq
é de longe a solução mais elegante. Comawk
você poderia escreverfonte
Para aqueles que não entendem avançado
awk
tão bem quanto gostariam (como pessoas como eu) e não têmjq
pré-instalado, uma solução fácil seria reunir alguns comandos nativos da seguinte forma:Se você está apenas tentando obter os valores, é mais fácil usar em
grep
vez deawk
oused
:Para fornecer uma explicação, esta parece ser a maneira mais simples para mim.
grep -A2
pega a linha que você está procurando no JSON, juntamente com as 2 linhas a seguir, que contêm a temperatura e a umidade.grep -o
simplesmente imprimir apenas dígitos numéricos separados por um.
(que nunca ocorrerá na primeira1490
linha, então você ficará com seus 2 valores - temperatura e umidade. Muito simples. Ainda mais simples do que usarjq
, na minha opinião.fonte
Minha ferramenta de escolha para processar JSON na linha de comandos é jq. No entanto, se você não possui o jq instalado, pode se sair muito bem com o Perl:
fonte
sua saída é um conjunto de snippets JSON em vez de um JSON completo. Se / uma vez que você reorganizar sua saída para ser um JSON integral, por exemplo, assim (assumindo que sua saída está dentro
file.json
):é fácil conseguir o que deseja com a
jtc
ferramenta (disponível em: https://github.com/ldn-softdev/jtc ):no exemplo acima, solte
-l
se você não quiser etiquetas impressasfonte