MQTTストリームから特定のデータを抽出する方法

MQTTストリームから特定のデータを抽出する方法

mosquitto_sub -d -t +/#Ubuntu端末から入力してMQTTストリームにアクセスします。

しかし、MQTTストリームの特定のデータセットだけを見たいです。 PING行を除くすべてのアイテムを追加しましたが、| grep -v PINGすべてのアイテムはまだ印刷されますが、機能しません。

MQTTでPUBLISHを含む行を確認するためにこれを試しましたが、| grep -A1 PUBLISH何も変更されませんでした。ちょうど完全なMQTTストリームを取得し、何もフィルタリングされませんでした。

MQTTストリームで見たい特定のコンテンツを表示するにはどうすればよいですか?それとも、MQTTストリームから何かをフィルタリングする方法、またはMQTTストリームからデータを抽出する方法は何ですか?

Ubuntu端末の私の入力は次のとおりです。$ 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の型文字列がすべての入力を安全に引用していることを確認し、各行ペアprintfでシェルコマンドを設定する方法で機能します。

各行のペアに対して、最初の行の内容を最初の行の中に印刷し、次にエポックの後の秒数を印刷し、次の改行でprintf2行目の内容を印刷します。出力は次のとおりです。\ndate[timestamp]\nsed

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

shもちろん、に印刷されたコマンドは、にsed印刷されるまで実行されません。したがって、sed読み取り出力に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

おすすめ記事