Como posso remover um retorno de carro, adicionar um carimbo de data / hora e ignorar alguns dados de um feed MQTT ativo

1

Eu digito mosquitto_sub -d -t +/# do terminal do Ubuntu para acessar o fluxo do MQTT.

A saída real do fluxo MQTT ao vivo é esta:

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

Não há como prever quando o próximo PUBLISH será visto, visto que eles são vistos apenas no stream quando o veículo tem transmissão / recepção das torres GSM / 3G

Para filtrar, eu adiciono mosquitto_sub -d -t +/# 2> >(grep PUBLISH) , isso só permite linhas com PUBLISH , portanto, a saída é:

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

Como eu seria capaz de eliminar alguns dos campos e também adicionar um carimbo de tempo toda vez que eu recebo alguma coisa; Eu tentei usar sed , mas não tive sorte. Eu digitei $ mosquitto_sub -d -t +/# 2< <(grep PUBLISH) 2< <(sed "s/^/ date / ") , $ mosquitto_sub -d -t +/# 2< <(grep PUBLISH) 2< <(sed "s/^/$ date '/")

P: Como posso alterar minha entrada para o terminal para que a saída do feed ativo acima seja:

[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

Soluções possíveis (referências futuras):

Usando o mosquitto_sub -d -t +/# 2> >(sed -n "s|.*\('.*',\).*||p") | sed "N;s/\n/ /;s/$/ $(date)/" A saída é:

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

Usando o comando mosquitto_sub -d -t +/# 2> >(grep PUBLISH) | sed "N;s/\n/ /;s/$/ $(date)/" do terminal, a saída é

817,3069000,60045,-33.836465,151.051189 609,24570,27553 27553 955 Thu Feb 26 00:06:26 UTC 2015

Usando o mosquitto_sub -d -t +/# 2>&1 | sed -n "/PUBLISH/{s|.*\('.*',\).*||;N;s/\n/ /;s/$/ $(date)/;p}" A saída é

'm/gf/MX3/122/d/status', 610,33000,28162,-33.836465,151.051189 Thu Feb 26 01:18:17 UTC 2015
    
por 3kstc 25.02.2015 / 02:30

2 respostas

2

Bem, bastante confuso, mas de qualquer maneira ... A julgar pela saída de mosquitto_sub -d -t +/# 2> >(grep PUBLISH)
seu aplicativo parece ter saída para stderr e stdout (caso contrário, você deve obter apenas linhas correspondentes a PUBLISH em sua saída). Ele imprime as mensagens de depuração ( Sending... e Received... ) para stderr e os dados reais ( 810,5440995,6143... ) para stdout .

Aparentemente, você precisa de valores separados por vírgulas para poder tentar o seguinte, se precisar do timestamp da linha correspondente a PUBLISH :

mosquitto_sub -d -t +/# 2>&1 | xargs -d$'\n' -L1 sh -c 'date "+%s,$0"' | \
sed -n "/PUBLISH/{N;s|[ /]|,|g;s|^\([^,]*,\)[^']*'\([^']*\)',.*\n[^,]*,\(.*\)|,|;p}"

ou, se você precisar do timestamp da próxima linha:

mosquitto_sub -d -t +/# 2>&1 | xargs -d$'\n' -L1 sh -c 'date "+%s,$0"' | \
sed -n "/PUBLISH/{N;s|[ /]|,|g;s|^[^,]*,[^']*'\([^']*\)',.*\n\([^,]*,\)\(.*\)|,|;p}"

2>&1 redireciona stderr para stdout , a saída é canalizada para xargs , que passa cada linha como um argumento para o próximo comando sh -c 'date "+%s,$0"' , então cada linha é prefixada com um timestamp + vírgula, por exemplo :

[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

Isso é canalizado para sed suprimindo a impressão automática ( -n ).
Para cada linha correspondente a PUBLISH , anexe a linha N ext, substitua cada espaço e / por vírgula, por meio de agrupamento, retenha apenas o primeiro ou o segundo registro de data e hora, os valores entre aspas e os valores após o segundo registro de data e hora finalmente, imprima o resultado:

[timestamp],m,NWRL,TMX,098,d,status,871,40114,4536,4536,323
    
por 03.03.2015 / 03:23
0

Eu simulei mosquitto no ambiente bash / ksh e encontrei

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

Eu usei sed aqui para cortar as partes interessantes.
Eu uso enquanto ler linha para uma maneira simples de juntar 2 linhas (e adicionar uma data). Isso é possível com sed ou tr, mas isso pode precisar de algum trabalho para (diferentes versões do sed).

Eu não entendo exatamente a chamada para o mosquitto_sub, então só mostro a solução quando as strings chegam por um pipe:

  • O que o # está fazendo lá?
    Sem aspas, deve ser o começo do comentário
  • Como você obtém uma linha com números quando você usa uma string?
    Os números são escritos para stderr? Depois de redirecioná-los para o stdout com 2>&1 grep, eles serão ignorados.
por 25.02.2015 / 21:33