나는 내 문제에 대한 해결책을 찾고 있었지만 해결책을 찾지 못했거나 더 나은 표현으로는 내가 찾은 해결책을 얻지 못했습니다. 내 질문은: 저는 Raspberry Pi에서 스마트 홈 제어 소프트웨어를 사용하고 있습니다. 사용pilight-receive
, 실외 온도 센서에서 데이터를 캡처할 수 있습니다. pilight-receive의 출력은 다음과 같습니다.
{
"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
}
이제 내 질문은 ID가 1490인 메시지에서 온도와 습도를 추출하는 방법입니다. 얼마나 자주 확인하라고 권하시나요? 10분마다 실행되는 cron 작업을 통해 출력을 생성하고 pilight-receive
출력 데이터를 추출하여 스마트 홈 제어 API에 푸시하시겠습니까?
답변1
jq
셸을 사용하여 json 파일을 처리 할 수 있습니다 .
예를 들어 샘플 json 파일을 다음과 같이 저장한 raul.json
후 다음을 실행했습니다.
$ jq .message.temperature raul.json
409.5
25.1
409.5
$ jq .message.humidity raul.json
null
40
null
잭대부분의 Linux 배포판에 대해 사전 패키징될 수 있습니다.
그 자체로 이 작업을 수행하는 방법이 있을 수 있지만 jq
한 줄에 두 개의 원하는 값을 얻는 가장 쉬운 방법은 다음을 사용하는 것입니다 xargs
.
$ jq 'select(.message.id == 1490) | .message.temperature, .message.humidity' raul.json | xargs
25.1 40
.message.id
또는 각 인스턴스를 반복하려는 경우 .message.id
출력에 추가하여 사용할 수 있습니다. xargs -n 3
세 가지 필드(id, 온도, 습도)가 있다는 것을 알고 있기 때문입니다.
jq '.message.id, .message.temperature, .message.humidity' raul.json | xargs -n 3
4095 409.5 null
1490 25.1 40
2039 409.5 null
그런 다음 awk 또는 다른 방법을 사용하여 이 출력을 사후 처리할 수 있습니다.
마지막으로, Python과 Perl 모두 json 데이터를 구문 분석하고 조작하기 위한 훌륭한 라이브러리를 가지고 있습니다. PHP와 Java를 포함한 다른 여러 언어와 마찬가지로.
답변2
나 같은 고급 기능에 대해 잘 모르고 사전 설치 awk
되어 있지 않은 사람들을 위한 jq
간단한 해결책은 다음과 같이 여러 기본 명령을 함께 연결하는 것입니다.
grep -A2 '"id": 1490,' stats.json | sed '/1490/d;s/"//g;s/,//;s/\s*//'
값만 얻으려면 or grep
대신 사용하는 awk
것이 더 쉽습니다 sed
.
grep -A2 '"id": 1490,' stats.json | grep -o "[0-9]*\.[0-9]*"
설명을 하자면 이 방법이 나에게는 가장 쉬운 방법인 것 같다.
grep -A2
JSON에서 찾고 있는 줄과 온도 및 습도가 포함된 다음 두 줄을 가져옵니다 .- 파이프는
grep -o
로 구분된 숫자만 인쇄합니다.
(첫 번째1490
줄에는 표시되지 않으므로 온도와 습도라는 두 가지 값만 남습니다. 매우 간단합니다.jq
제 생각에는 를 사용하는 것보다 훨씬 간단합니다.
답변3
명령줄에서 JSON을 처리하기 위해 제가 선택한 도구는 jq입니다. 그러나 jq가 설치되어 있지 않으면 Perl을 사용해도 됩니다.
# perl -MJSON -e '$/ = undef; my $data = <>; for my $hash (new JSON->incr_parse($data)) { my $msg = $hash->{message}; print "$msg->{temperature} $msg->{humidity}\n" if $msg->{id} == 1490 }' < data.json
25.1 40
답변4
출력은 완전한 JSON이 아닌 JSON 조각 세트입니다. 출력을 전체 JSON으로 다시 정렬하는 경우(예: 출력이 에 있다고 가정 file.json
):
echo "[ $(cat file.json | sed -E 's/^}$/},/; $d') }]"
그러면 jtc
도구를 사용하여 원하는 것을 쉽게 얻을 수 있습니다(다음 위치에서 사용 가능).https://github.com/ldn-softdev/jtc):
bash $ echo "[ $(cat file.json | sed -E 's/^}$/},/; $d') }]" | jtc -x "[id]:<1490>d [-1]" -y[temperature] -y[humidity] -l
"temperature": 25.1
"humidity": 40.0
bash $
위의 예에서 -l
라벨을 인쇄할 필요가 없으면 제거하세요.