Tengo bin buscando una solución para mi pregunta, pero no encontré una o mejor, dije que no la obtuve con lo que encontré. Así que hablemos de cuál es mi problema. Estoy usando un software de control inteligente para el hogar en una Raspberry Pi y, como descubrí este fin de semana usando la recepción de pilight, puedo capturar los datos de mi sensor de temperatura exterior. La salida de Pilight-Recibir se ve así:
{
"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
}
Ahora mi pregunta para usted: ¿Cómo diablos puedo extraer la temperatura y la humedad de donde está la identificación 1490. ¿Y cómo me recomendaría que verifique esto con frecuencia? Mediante un trabajo cron que se ejecuta cada 10 minutos, crea una salida de la recepción de pilight, extrae los datos de la salida y los envía a la API de Smart Home Control.
Alguien que tiene una idea, muchas gracias
fuente

awkysedsiempre que la salida JSON conserve el formato que se muestra aquí, lo cual no es necesario; el espacio en blanco no importa para JSON. Por ejemplo, esteawkcomando:awk '/temperature|humidity/ {print $2}'está cerca.ksh93análisis json está incorporado aread.Respuestas:
Puede usar
jqpara procesar archivos json en shell.Por ejemplo, guardé su archivo json de muestra como
raul.jsony luego ejecuté:jq está disponible preempaquetado para la mayoría de las distribuciones de Linux.
Probablemente hay una forma de hacerlo en
jqsí mismo, pero la forma más simple que encontré para obtener los dos valores deseados en una línea es usarxargs. Por ejemplo:o, si desea recorrer cada
.message.idinstancia, podemos agregar.message.ida la salida y usar,xargs -n 3ya que sabemos que habrá tres campos (id, temperatura, humedad):Luego, puede procesar posteriormente esa salida con awk o lo que sea.
Finalmente, tanto python como perl tienen excelentes bibliotecas para analizar y manipular datos json. Al igual que varios otros idiomas, incluidos php y java.
fuente
jq 'select(.message.id == 1490) | .message.temperature, .message.humidity' raul.json{ read temp; read hum; } < <(jq ...)grep. Puede que no funcione para algunas versiones específicas degrep, pero es más sencillo quejqen este escenario, aunquejqestá diseñado específicamente para analizar JSON. Sin embargo, le dijqun voto positivo a la respuesta. De hecho, es una herramienta para el trabajo, pero a veces simplemente puede quitar las grapas con los dedos en lugar de buscar un quitagrapas.jqes uno de los scripts de shell. otros idiomas tienen bibliotecas de análisis json.jqque lo hacejqEs, con mucho, la solución más elegante. Contigoawkpodrías escribirfuente
Para aquellos que no entienden el avanzado
awktan bien como les gustaría (como personas como yo) y no tienenjqpreinstalado, una solución fácil sería unir un par de comandos nativos de la siguiente manera:Si solo está tratando de obtener los valores, es más fácil usar en
greplugar deawkosed:Para dar una explicación, esta me parece la forma más simple.
grep -A2agarra la línea que busca en el JSON, junto con las 2 líneas siguientes, que contienen la temperatura y la humedad.grep -osimplemente imprime solo dígitos numéricos separados por un.(lo que nunca ocurrirá en la primera1490línea, por lo que le quedan sus 2 valores: temperatura y humedad. Muy simple. Incluso más simple que usarjq, en mi opinión.fuente
Mi herramienta de elección para procesar JSON en la línea de comando es jq. Sin embargo, si no tiene instalado jq, puede hacerlo bastante bien con Perl:
fuente
su salida es un conjunto de fragmentos JSON en lugar de un JSON completo. Si / una vez que reorganiza su salida para que sea un JSON integral, por ejemplo, así (suponiendo que su salida esté en
file.json):entonces es fácil lograr lo que desea con la
jtcherramienta (disponible en: https://github.com/ldn-softdev/jtc ):en el ejemplo anterior, suelte
-lsi no desea etiquetas impresasfuente