Ich habe nach einer Lösung für meine Frage gesucht, aber keine gefunden oder besser gesagt, ich habe sie nicht mit dem bekommen, was ich gefunden habe. Sprechen wir also darüber, worum es bei meinem Problem geht. Ich verwende eine Smart Home Control Software auf einem Raspberry Pi und wie ich an diesem Wochenende mit pilight-receive herausgefunden habe, kann ich die Daten von meinem Außentemperatursensor abrufen. Die Ausgabe von pilight-receive sieht folgendermaßen aus:
{
"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
}
Nun meine Frage an Sie: Wie zum Teufel kann ich die Temperatur und Luftfeuchtigkeit von der ID 1490 extrahieren? Und wie würden Sie mir empfehlen, dies regelmäßig zu überprüfen? Durch einen Cron-Job, der alle 10 Minuten ausgeführt wird, eine Ausgabe des Pilight-Empfangs erstellt, die Daten der Ausgabe extrahiert und an die Smart Home Control-API übermittelt.
Jemand, der eine Idee hat - vielen Dank
quelle
awk
undsed
vorausgesetzt, die JSON-Ausgabe behält die hier gezeigte Formatierung bei, die sie nicht benötigt - Leerzeichen spielen für JSON keine Rolle. Zum Beispiel ist dieserawk
Befehl:awk '/temperature|humidity/ {print $2}'
close.ksh93
json ist das parsing dazu eingebautread
.Antworten:
Mit können Sie
jq
JSON-Dateien in der Shell verarbeiten.Ich habe beispielsweise Ihre Beispiel-JSON-Datei als gespeichert
raul.json
und dann ausgeführt:jq ist für die meisten Linux-Distributionen vorinstalliert.
Es gibt wahrscheinlich eine Möglichkeit, dies
jq
selbst zu tun , aber die einfachste Möglichkeit, die beiden gewünschten Werte in einer Zeile zu erhalten, ist die Verwendungxargs
. Beispielsweise:oder, wenn Sie jede
.message.id
Instanz durchlaufen möchten , können wir.message.id
die Ausgabe erweitern und verwenden,xargs -n 3
da wir wissen, dass es drei Felder gibt (ID, Temperatur, Luftfeuchtigkeit):Sie können diese Ausgabe dann mit awk oder was auch immer nachbearbeiten.
Schließlich verfügen sowohl Python als auch Perl über hervorragende Bibliotheken zum Parsen und Bearbeiten von JSON-Daten. Wie einige andere Sprachen, einschließlich PHP und Java.
quelle
jq 'select(.message.id == 1490) | .message.temperature, .message.humidity' raul.json
{ read temp; read hum; } < <(jq ...)
grep
. Es funktioniert möglicherweise nicht für bestimmte Versionen vongrep
, ist aber einfacher alsjq
in diesem Szenario, obwohljq
es speziell für das Parsen von JSON entwickelt wurde.jq
Trotzdem habe ich die Antwort positiv bewertet. Es ist in der Tat ein Werkzeug für den Job, aber manchmal können Sie Heftklammern einfach mit Ihren Fingern entfernen, anstatt nach einem Klammerentferner zu suchen.jq
ist eine solche für Shell-Skripte. Andere Sprachen haben JSON-Parsing-Bibliotheken.jq
tut esjq
ist mit Abstand die eleganteste Lösung. Mitawk
könntest du schreibenquelle
Für diejenigen, die Advanced nicht
awk
so gut verstehen, wie sie esjq
möchten (wie Leute wie ich) und die es nicht vorinstalliert haben, wäre eine einfache Lösung, ein paar native Befehle wie folgt zusammenzufügen:Wenn Sie nur versuchen, die Werte zu ermitteln, ist es einfacher,
grep
stattawk
oder nur Folgendes zu verwendensed
:Um eine Erklärung zu geben, scheint mir dies der einfachste Weg zu sein.
grep -A2
greift nach der Zeile, die Sie im JSON suchen, zusammen mit den folgenden 2 Zeilen, die die Temperatur und Luftfeuchtigkeit enthalten.grep -o
einfach nur numerische Ziffern aus, die durch ein.
(das wird in der ersten1490
Zeile nie vorkommen) getrennt sind, sodass Sie Ihre 2 Werte - Temperatur und Luftfeuchtigkeit - behalten. Sehr einfach. Noch einfacher als die Verwendungjq
, meiner Meinung nach.quelle
Mein bevorzugtes Werkzeug für die Verarbeitung von JSON in der Befehlszeile ist jq. Wenn Sie jedoch jq nicht installiert haben, können Sie Perl recht gut einsetzen:
quelle
Ihre Ausgabe besteht aus einer Reihe von JSON-Snippets und nicht aus einer vollständigen JSON. Wenn / sobald Sie Ihre Ausgabe zu einem integralen JSON umgestalten, z. B. so (vorausgesetzt, Ihre Ausgabe ist in
file.json
):Dann ist es einfach, mit dem
jtc
Tool das zu erreichen, was Sie wollen (verfügbar unter: https://github.com/ldn-softdev/jtc ):Im obigen Beispiel löschen
-l
Sie, wenn Sie keine gedruckten Etiketten möchtenquelle