J'ai bin à la recherche d'une solution à ma question, mais je n'ai pas trouvé de réponse ou mieux dit que je ne l'ai pas trouvée avec ce que j'ai trouvé. Permet donc de parler de mon problème. J'utilise un logiciel de contrôle de maison intelligente sur un Raspberry Pi et comme je l'ai découvert ce week-end en utilisant la réception pilight, je peux capturer les données de mon capteur de température extérieure. La sortie de pilight-receive ressemble à ceci:
{
"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
}
Maintenant ma question pour vous: comment diable puis-je extraire la température et l'humidité de l'endroit où l'id est 1490. Et comment me recommanderiez-vous de vérifier cela fréquemment? Par un travail cron qui s'exécute toutes les 10 minutes, crée une sortie de la réception pilight, extrait les données de la sortie et les pousse vers l'API Smart Home Control.
Quelqu'un a une idée - merci beaucoup
la source
awk
et àsed
condition que la sortie JSON conserve le formatage montré ici, ce qui n'est pas nécessaire - les espaces blancs n'ont pas d'importance pour JSON. Par exemple, cetteawk
commande:awk '/temperature|humidity/ {print $2}'
est proche.ksh93
analyse json est intégré àread
.Réponses:
Vous pouvez utiliser
jq
pour traiter les fichiers json en shell.Par exemple, j'ai enregistré votre exemple de fichier json sous
raul.json
, puis j'ai exécuté:jq est disponible pré-emballé pour la plupart des distributions Linux.
Il y a probablement un moyen de le faire en
jq
soi, mais le moyen le plus simple que j'ai trouvé pour obtenir les deux valeurs souhaitées sur une seule ligne est d'utiliserxargs
. Par exemple:ou, si vous voulez parcourir chaque
.message.id
instance, nous pouvons ajouter.message.id
à la sortie et utiliserxargs -n 3
car nous savons qu'il y aura trois champs (id, température, humidité):Vous pouvez ensuite post-traiter cette sortie avec awk ou autre chose.
Enfin, python et perl ont d'excellentes bibliothèques pour analyser et manipuler les données json. Comme le font plusieurs autres langues, dont php et java.
la source
jq 'select(.message.id == 1490) | .message.temperature, .message.humidity' raul.json
{ read temp; read hum; } < <(jq ...)
grep
. Il peut ne pas fonctionner pour certaines versions spécifiques degrep
, mais il est plus simple quejq
dans ce scénario, même s'iljq
est conçu spécifiquement pour l'analyse JSON. J'ai quand même donnéjq
une réponse positive à la réponse. C'est en effet un outil pour le travail, mais parfois vous pouvez simplement retirer les agrafes avec vos doigts plutôt que de chercher un décapant d'agrafes.jq
en fait partie pour les scripts shell. d'autres langues ont des bibliothèques d'analyse json.jq
cela fonctionne?jq
est de loin la solution la plus élégante. Avecawk
vous pourriez écrirela source
Pour ceux qui ne comprennent pas le niveau avancé
awk
aussi bien qu'ils le souhaiteraient (comme des gens comme moi) et qui n'ont pas dejq
pré-installation, une solution simple serait de canaliser quelques commandes natives ensemble comme ceci:Si vous essayez seulement d'obtenir les valeurs, il est plus facile d'utiliser
grep
plutôt queawk
oused
:Pour fournir une explication, cela me semble être le moyen le plus simple.
grep -A2
saisit la ligne que vous recherchez dans le JSON avec les 2 lignes suivantes, qui contiennent la température et l'humidité.grep -o
imprime simplement uniquement des chiffres numériques séparés par un.
(qui ne se produira jamais sur la première1490
ligne, donc vous vous retrouvez avec vos 2 valeurs - température et humidité. Très simple. Encore plus simple que d'utiliserjq
, à mon avis.la source
Mon outil de choix pour le traitement de JSON sur la ligne de commande est jq. Cependant, si jq n'est pas installé, vous pouvez très bien faire avec Perl:
la source
votre sortie est un ensemble d'extraits JSON plutôt qu'un JSON complet. Si / une fois que vous réorganisez votre sortie pour qu'elle soit un JSON intégral, par exemple comme ceci (en supposant que votre sortie est dedans
file.json
):alors il est facile de réaliser ce que vous voulez avec l'
jtc
outil (disponible sur: https://github.com/ldn-softdev/jtc ):dans l'exemple ci-dessus, supprimez
-l
si vous ne voulez pas d'étiquettes impriméesla source