我mosquitto_sub -d -t +/#
从 Ubuntu 终端输入来访问 MQTT 流。
实时 MQTT 流的实际输出是这样的:
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
Received PUBLISH (d0, q0, r0, m0, 'm/NWRL/TMX/098/d/SVlts', ... (26 bytes))
806,3040421,7549 7750 3904
Received PUBLISH (d0, q0, r0, m0, 'm/NWRL/TMX/098/d/status', ... (39 bytes))
806,3069000,59666,-33.836465,151.051189
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Received PUBLISH (d0, q0, r0, m0, 'm/NWRL/TMX/098/d/SVlts', ... (26 bytes))
810,5440995,6143 7807 4076
Sending PINGREQ
Received PINGRESP
Received PUBLISH (d0, q0, r0, m0, 'm/NWRL/TMX/098/d/status', ... (39 bytes))
810,5489000,59897,-33.836465,151.051189
Sending PINGREQ
Received PINGRESP
无法预测何时会看到下一个 PUBLISH,因为只有当车辆从 GSM/3G 塔进行传输/接收时才能在流中看到它们
为了过滤,我添加mosquitto_sub -d -t +/# 2> >(grep PUBLISH)
这将只允许PUBLISH
其中包含行,因此输出是:
Received PUBLISH (d0, q0, r0, m0, 'm/gf/TMX6BP/075/d/status', ... (38 bytes))
86,637999,164563,-33.836465,151.051189
Received PUBLISH (d0, q0, r0, m0, 'm/NWRL/TMX/098/d/SVlts', ... (26 bytes))
806,3040421,7549 7750 3904
Received PUBLISH (d0, q0, r0, m0, 'm/NWRL/TMX/098/d/status', ... (39 bytes))
806,3069000,59666,-33.836465,151.051189
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
Received PUBLISH (d0, q0, r0, m0, 'm/NWRL/TMX/098/d/SVlts', ... (26 bytes))
806,3640483,7463 7721 3933
Received PUBLISH (d0, q0, r0, m0, 'm/NWRL/TMX/098/d/status', ... (39 bytes))
806,3674000,59676,-33.836465,151.051189
Received PUBLISH (d0, q0, r0, m0, 'm/NWRL/TMX/098/d/SVlts', ... (26 bytes))
806,4240543,7291 7750 3933
Received PUBLISH (d0, q0, r0, m0, 'm/NWRL/TMX/098/d/status', ... (39 bytes))
806,4279000,59687,-33.836465,151.051189
Received PUBLISH (d0, q0, r0, m0, 'm/gf/MXE/065/d/SVlts', ... (25 bytes))
455,24715,28041 28041 967
我怎样才能消除一些字段,并在每次收到东西时添加时间戳?我尝试过使用sed
但没有运气。我进入了,$ mosquitto_sub -d -t +/# 2< <(grep PUBLISH) 2< <(sed "s/^/
date
/")$ mosquitto_sub -d -t +/# 2< <(grep PUBLISH) 2< <(sed "s/^/$
date`/")
问:如何更改终端的输入,以便上述实时源的输出为:
[timestamp],m,gf,TMX6BP,075,d,status,86,637999,164563,-33.836465,151.051189
[timestamp],m,NWRL,TMX,098,d,SVlts,806,3040421,7549 7750 3904
[timestamp],m,NWRL,TMX,098,d,status,806,3069000,59666,-33.836465,151.051189
[timestamp],m,gf,TMX6BP,075,d,SVlts,86,1224830,27610 27869 17565
[timestamp],m,gf,TMX6BP,075,d,status,86,1243000,164573,-33.836465,151.051189
[timestamp],m,NWRL,TMX,098,d,SVlts,806,3640483,7463 7721 3933
[timestamp],m,NWRL,TMX,098,d,status,806,3674000,59676,-33.836465,151.051189
[timestamp],m,NWRL,TMX,098,d,SVlts,806,4240543,7291 7750 3933
[timestamp],m,NWRL,TMX,098,d,status,806,4279000,59687,-33.836465,151.051189
[timestamp],m,gf,MXE,065,d,SVlts,455,24715,28041 28041 967
可能的解决方案(将来参考):
使用mosquitto_sub -d -t +/# 2> >(sed -n "s|.*\('.*',\).*|\1|p") | sed "N;s/\n/ /;s/$/ $(date)/"
输出是:
0 810,5440995,6143 7807 4076 Wed Feb 25 23:23:51 UTC 2015 810,5489000,59897,-33.836465,151.051189 810,6041055,7606 7693 4076 Wed Feb 25 23:23:51 UTC 2015
使用mosquitto_sub -d -t +/# 2> >(grep PUBLISH) | sed "N;s/\n/ /;s/$/ $(date)/"
终端命令的输出是
817,3069000,60045,-33.836465,151.051189 609,24570,27553 27553 955 Thu Feb 26 00:06:26 UTC 2015
使用mosquitto_sub -d -t +/# 2>&1 | sed -n "/PUBLISH/{s|.*\('.*',\).*|\1|;N;s/\n/ /;s/$/ $(date)/;p}"
输出是
'm/gf/MX3/122/d/status', 610,33000,28162,-33.836465,151.051189 Thu Feb 26 01:18:17 UTC 2015
答案1
好吧,相当令人困惑,但无论如何......从应用程序的输出来看,
mosquitto_sub -d -t +/# 2> >(grep PUBLISH)
似乎同时输出到stderr
and stdout
(否则你应该只得到PUBLISH
输出中匹配的行)。它将调试消息 (Sending...
和Received...
) 打印到stderr
,并将实际数据 ( 810,5440995,6143...
) 打印到stdout
。
显然,您需要逗号分隔值,因此如果您需要匹配行的时间戳,则可以尝试以下操作PUBLISH
:
mosquitto_sub -d -t +/# 2>&1 | xargs -d$'\n' -L1 sh -c 'date "+%s,$0"' | \
sed -n "/PUBLISH/{N;s|[ /]|,|g;s|^\([^,]*,\)[^']*'\([^']*\)',.*\n[^,]*,\(.*\)|\1\2,\3|;p}"
或者,如果您需要下一行的时间戳:
mosquitto_sub -d -t +/# 2>&1 | xargs -d$'\n' -L1 sh -c 'date "+%s,$0"' | \
sed -n "/PUBLISH/{N;s|[ /]|,|g;s|^[^,]*,[^']*'\([^']*\)',.*\n\([^,]*,\)\(.*\)|\2\1,\3|;p}"
2>&1
重定向stderr
到stdout
,然后将输出通过管道传递到xargs
,将每行作为参数传递给下一个命令sh -c 'date "+%s,$0"'
,因此每行前面都带有时间戳+逗号,例如:
[timestamp],Sending PINGREQ
[timestamp],Received PINGRESP
[timestamp],Received PUBLISH (d0, q0, r0, m0, 'm/NWRL/TMX/098/d/status', ... (39 bytes))
[timestamp],871,40114,4536 4536 323
然后通过管道来sed
抑制自动打印 ( -n
)。
对于匹配的每一行PUBLISH
,附加N
ext 行,替换每个空格并/
用逗号然后通过分组,仅保留第一个或第二个时间戳,引号之间的值以及第二个时间戳之后的值,最后打印结果:
[timestamp],m,NWRL,TMX,098,d,status,871,40114,4536,4536,323
答案2
我在bash/ksh环境下模拟mosquitto,发现
stub_mosquitto |
sed -e 's/.*m0, //' -e 's/, .*bytes))//' | while read line; do
if [[ "${line}" = \'* ]]; then
echo -n "${line}, "
else
echo "${line}, $(date)"
fi
done
我在这里使用 sed 来剪切有趣的部分。
我使用 while read 行作为连接两行(并添加日期)的简单方法。这对于 sed 或 tr 是可能的,但这可能需要一些工作(不同版本的 sed)。
我不完全理解对 mosquitto_sub 的调用,因此我仅在字符串通过管道时显示解决方案:
- 在那里做什么
#
?
如果没有引号,它应该是评论的开头 - grep 查找字符串时如何获得包含数字的行?
这些数字是否写入 stderr?使用 grep 将它们重定向到标准输出后将2>&1
跳过它们。