如何删除回车符、添加时间戳并忽略实时 MQTT 源中的某些数据

如何删除回车符、添加时间戳并忽略实时 MQTT 源中的某些数据

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)
似乎同时输出到stderrand 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重定向stderrstdout,然后将输出通过管道传递到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,附加Next 行,替换每个空格并/用逗号然后通过分组,仅保留第一个或第二个时间戳,引号之间的值以及第二个时间戳之后的值,最后打印结果:

[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跳过它们。

相关内容