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
awk
ysed
siempre 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, esteawk
comando:awk '/temperature|humidity/ {print $2}'
está cerca.ksh93
análisis json está incorporado aread
.Respuestas:
Puede usar
jq
para procesar archivos json en shell.Por ejemplo, guardé su archivo json de muestra como
raul.json
y luego ejecuté:jq está disponible preempaquetado para la mayoría de las distribuciones de Linux.
Probablemente hay una forma de hacerlo en
jq
sí 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.id
instancia, podemos agregar.message.id
a la salida y usar,xargs -n 3
ya 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 quejq
en este escenario, aunquejq
está diseñado específicamente para analizar JSON. Sin embargo, le dijq
un 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.jq
es uno de los scripts de shell. otros idiomas tienen bibliotecas de análisis json.jq
que lo hacejq
Es, con mucho, la solución más elegante. Contigoawk
podrías escribirfuente
Para aquellos que no entienden el avanzado
awk
tan bien como les gustaría (como personas como yo) y no tienenjq
preinstalado, 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
grep
lugar deawk
osed
:Para dar una explicación, esta me parece la forma más simple.
grep -A2
agarra la línea que busca en el JSON, junto con las 2 líneas siguientes, que contienen la temperatura y la humedad.grep -o
simplemente imprime solo dígitos numéricos separados por un.
(lo que nunca ocurrirá en la primera1490
lí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
jtc
herramienta (disponible en: https://github.com/ldn-softdev/jtc ):en el ejemplo anterior, suelte
-l
si no desea etiquetas impresasfuente