Saya memiliki bin mencari solusi untuk pertanyaan saya tetapi tidak menemukan atau lebih baik mengatakan saya tidak mendapatkannya dengan apa yang saya temukan. Jadi mari kita bicara tentang masalah saya. Saya menggunakan Smart Home Control Software pada Raspberry Pi dan ketika saya mengetahui akhir pekan ini menggunakan pilight-accept, saya dapat menangkap data dari sensor suhu luar ruang saya. Output Pilight-accept terlihat seperti itu:
{
"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
}
Sekarang pertanyaan saya kepada Anda: Bagaimana sih saya bisa mengekstraksi suhu dan kelembaban dari tempat id adalah 1490. Dan bagaimana Anda merekomendasikan saya untuk melakukan ini? Dengan pekerjaan cron yang berjalan setiap 10 menit, menciptakan output dari Pilight-accept, mengekstrak data output dan mendorongnya ke Smart Home Control Api.
Seseorang yang punya ide - terima kasih banyak
sumber
awk
dansed
asalkan output JSON mempertahankan format yang ditunjukkan di sini, yang tidak perlu - spasi putih tidak masalah untuk JSON. Sebagai contoh,awk
perintah ini :awk '/temperature|humidity/ {print $2}'
sudah dekat.ksh93
parsing json dibangun untukread
.Jawaban:
Anda dapat menggunakan
jq
untuk memproses file json di shell.Misalnya, saya menyimpan file json sampel Anda sebagai
raul.json
dan kemudian berlari:jq tersedia pra-paket untuk sebagian besar distro linux.
Mungkin ada cara untuk melakukannya
jq
sendiri, tetapi cara paling sederhana yang saya temukan untuk mendapatkan kedua nilai yang diinginkan pada satu baris adalah dengan menggunakannyaxargs
. Sebagai contoh:atau, jika Anda ingin mengulang setiap
.message.id
contoh, kita dapat menambahkan.message.id
ke output dan menggunakanxargs -n 3
seperti yang kita tahu bahwa akan ada tiga bidang (id, suhu, kelembaban):Anda kemudian dapat memposting proses itu dengan awk atau apa pun.
Akhirnya, baik python dan perl memiliki pustaka yang sangat baik untuk mem-parsing dan memanipulasi data json. Seperti halnya beberapa bahasa lain, termasuk php dan java.
sumber
jq 'select(.message.id == 1490) | .message.temperature, .message.humidity' raul.json
{ read temp; read hum; } < <(jq ...)
grep
. Ini mungkin tidak bekerja untuk beberapa versi tertentugrep
, tetapi lebih mudah daripadajq
dalam skenario ini, meskipunjq
dirancang khusus untuk mem-parsing JSON. Saya memang memberikanjq
jawaban yang mendukung, bagaimanapun. Ini memang alat untuk pekerjaan itu, tetapi kadang-kadang Anda bisa dengan mudah melepas staples dengan jari Anda daripada mencari-cari penghapus staples.jq
adalah salah satunya untuk skrip shell. bahasa lain memiliki parsing perpustakaan json.jq
melakukannya?jq
sejauh ini merupakan solusi yang paling elegan. Denganawk
Anda bisa menulissumber
Bagi mereka yang tidak mengerti tingkat lanjut
awk
seperti yang mereka inginkan (seperti orang-orang seperti saya) dan tidak memilikijq
pra-instal, solusi mudah akan menyalurkan beberapa perintah asli bersama-sama seperti:Jika Anda hanya mencoba untuk mendapatkan nilai, lebih mudah hanya menggunakan
grep
daripadaawk
ataused
:Untuk memberikan penjelasan, ini sepertinya cara paling sederhana bagi saya.
grep -A2
meraih garis yang Anda cari dalam JSON bersama dengan 2 baris berikut, yang berisi suhu dan kelembaban.grep -o
hanya mencetak digit angka yang dipisahkan oleh.
(yang tidak akan pernah terjadi pada1490
baris pertama , sehingga Anda dibiarkan dengan 2 nilai Anda - suhu dan kelembaban. Sangat sederhana. Bahkan lebih sederhana daripada menggunakanjq
, menurut saya.sumber
Alat pilihan saya untuk memproses JSON pada baris perintah adalah jq. Namun, jika Anda tidak menginstal jq, Anda dapat melakukannya dengan cukup baik dengan Perl:
sumber
output Anda adalah satu set cuplikan JSON daripada JSON lengkap. Jika / setelah Anda mengatur ulang output Anda menjadi JSON yang tidak terpisahkan, misal seperti ini (dengan asumsi output Anda ada dalam
file.json
):maka mudah untuk mencapai apa yang Anda inginkan dengan
jtc
alat (tersedia di: https://github.com/ldn-softdev/jtc ):pada contoh drop di atas
-l
jika Anda tidak ingin label yang dicetaksumber