MQTT 스트림에서 특정 데이터를 추출하는 방법

MQTT 스트림에서 특정 데이터를 추출하는 방법

mosquitto_sub -d -t +/#Ubuntu 터미널에서 입력하여 MQTT 스트림에 액세스합니다 .

그러나 MQTT 스트림의 특정 데이터 세트만 보고 싶습니다. PING 줄을 제외한 모든 항목을 추가했는데 | grep -v PING모든 항목이 여전히 인쇄되지만 작동하지 않습니다.

MQTT에서 PUBLISH가 포함된 행을 확인하기 위해 이것을 시도했지만 | grep -A1 PUBLISH아무 것도 변경되지 않았습니다. 단지 전체 MQTT 스트림을 얻었고 아무 것도 필터링되지 않았습니다.

MQTT 스트림에서 보고 싶은 특정 콘텐츠를 보려면 어떻게 해야 합니까? 아니면 MQTT 스트림에서 무언가를 필터링하는 방법이나 MQTT 스트림에서 데이터를 추출하는 방법은 무엇입니까?

우분투 터미널의 내 입력은 다음과 같습니다 . $ mosquitto_sub -d -t +/#시도해 보았지만 모든 것을 스트리밍하고 아무것도 grep하지 않습니다. 출력은 다음과 같습니다.$ mosquitto_sub -d -t +/# | grep -v PING$ mosquitto_sub -d -t +/# | grep -A1 PUBLISH

ed@agharta:~$ mosquitto_sub -d -t +/#
Received CONNACK
Received SUBACK
Subscribed (mid: 1): 0
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Received PUBLISH (d0, q0, r0, m0, 'm/jsyd/TEST/001/d/status', ... (34 bytes))
Sending PINGREQ
Received PINGRESP
Received PUBLISH (d0, q0, r0, m0, 'm/jsyd/TEST/001/d/SVlts', ... (28 bytes))
Sending PINGREQ
Received PINGRESP

예를 들어 어떻게 할 수 있습니까?오직라이브 방송에서 PING 대신 PUBLISH가 표시되나요?

답변1

다른 관련 질문에 대해 다음 답변을 쓰고 있습니다.여기제거되면. 링크를 클릭해도 될지는 모르겠지만,(약어)아래에 언급된 샘플 데이터는 다음과 같습니다.

Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Received PUBLISH (d0, q0, r0, m0, 'm/gf/TMX6BP/075/d/SVlts', ... (28 bytes))
86,1224830,27610 27869 17565
Received PUBLISH (d0, q0, r0, m0, 'm/gf/TMX6BP/075/d/status', ... (39 bytes))
86,1243000,164573,-33.836465,151.051189
Sending PINGREQ
Received PINGRESP

sed그래서 다음과 같이 작동하도록 다음과 같이 썼습니다.

mosquitto ... 2>&1 | 
sed -u "/.*PUBLISH[^']*\([^,]*,\).*/!d 
       s//\1/;N;s/[\%]/&&/g;s/'/&\\\\&&/g
       s/.*/printf '&'/;s/\n/'&date '+[%s,]/"|  
sh -s

이제 귀하의 프로그램이 없지만 mosquitto예제의 전체 내용을 클립보드에 복사한 후 다음을 수행하십시오.

xsel -bo | sed ... | sh ...

다음과 같이 인쇄됩니다.

'm/gf/TMX6BP/075/d/SVlts',[1425002404,]86,1224830,27610 27869 17565
'm/gf/TMX6BP/075/d/status',[1425002404,]86,1243000,164573,-33.836465,151.051189
'm/NWRL/TMX/098/d/SVlts',[1425002404,]806,3040421,7549 7750 3904
'm/NWRL/TMX/098/d/status',[1425002404,]806,3069000,59666,-33.836465,151.051189
'm/NWRL/TMX/098/d/SVlts',[1425002404,]810,5440995,6143 7807 4076
'm/NWRL/TMX/098/d/status',[1425002404,]810,5489000,59897,-33.836465,151.051189

...그게 당신이 원하는 것 같군요. 이는 쉘과 datefor의 형식 문자열이 모든 input을 안전하게 인용하는지 확인한 printf다음 각 행 쌍에서 쉘 명령을 구성하는 방식으로 작동합니다.

각 줄 쌍에 대해 printf먼저 후행 \n줄눈 없이 첫 번째 줄의 내용을 인쇄한 다음 에포크 이후의 초 수를 date인쇄한 다음 뒤따르는 줄 바꿈과 함께 두 번째 줄의 내용을 인쇄합니다. 출력은 다음과 같습니다.[timestamp]\nsed

printf ''\''m/gf/TMX6BP/075/d/SVlts'\'','
date '+[%s,]86,1224830,27610 27869 17565'

sh물론, 에 인쇄된 명령은 sed에 인쇄될 때까지 실행되지 않습니다. 따라서 sedread 출력에 mosquitto이전 줄보다 뒤에 있는 줄이 있으면 해당 date줄이 이를 반영합니다.

예를 들어:

(set -f; IFS='
';  for l in $(xsel -bo)
    do  printf %s\\n "$l"
        sleep 1
    done) |
sed -u "/.*PUBLISH[^']*\([^,]*,\).*/!d 
       s//\1/;N;s/[\%]/&&/g;s/'/&\\\\&&/g
       s/.*/printf '&'/;s/\n/'&date '+[%s,]/"|  
sh -s

sed... 라이브 스트림을 보다 충실하게 시뮬레이션하려면 각 출력 라인을 인쇄하기 전에 1초 정도 기다리십시오 . GNU sed -unbuffered 스위치를 활용하여 가능한 한 자주 출력을 플러시하지만, 그렇게 할 수 없는 경우 알려주시면 버퍼링 문제를 피하기 sed위해 파이프를 올바르게 차단하는 방법을 보여 드리겠습니다 .dd

어쨌든 위의 내용은 다음과 같이 인쇄됩니다.

'm/gf/TMX6BP/075/d/SVlts',[1425002863,]86,1224830,27610 27869 17565
'm/gf/TMX6BP/075/d/status',[1425002865,]86,1243000,164573,-33.836465,151.051189
'm/NWRL/TMX/098/d/SVlts',[1425002869,]806,3040421,7549 7750 3904
'm/NWRL/TMX/098/d/status',[1425002871,]806,3069000,59666,-33.836465,151.051189
'm/NWRL/TMX/098/d/SVlts',[1425002881,]810,5440995,6143 7807 4076
'm/NWRL/TMX/098/d/status',[1425002885,]810,5489000,59897,-33.836465,151.051189

관련 정보