Extrai o tempo entre os eventos do arquivo de log no Bash

0

Eu tenho um arquivo /tmp/log/1GPS_garmin2.log e quero calcular quanto tempo passou entre a primeira e a última parada de um veículo.

Aqui está uma amostra dos dados:

181225.249849952:,06,,14,18,19,22,27,32,,,2.0,1.4,1.5*34
181225.254218266:$GPVTG,000.0,T,355.7,M,000.01,N,**0000**.02,K*79
181225.259072464:$GPRMC,161212.2,A,4653.89701,N,01940.55676,E,000.01,000.0,100913,004.3,E*59
181225.264592889:$GPGGA,**161212**.2,4653.89701,N,01940.55676,E,2,08,1.4,124.2,M,41.3,M,,*5C
181225.268283132:$GPGSA,A,3,,03,06,,14,18,19,22,27,32,,,2.0,1.4,1.5*34
181225.274272586:$GPVTG,000.0,T,355.7,M,000.01,N,0000.01,K*7A
181225.277401076:$GPRMC,161212.4,A,4653.89701,N,01940.55676,E,000.01,000.0,100913,004.3,E*5F
181225.280493945:$GPGGA,161212.4,4653.89701,N,01940.55676,E,2,08,1.4,124.2,M,41.3,M,,*5A
181225.283556186:$GPGSA,A,3,,03,06,,14,18,19,22,27,32,,,2.0,1.4,1.5*34
181225.286888004:$GPVTG,000.0,T,355.7,M,000.01,N,0000.01,K*7A
181225.290137581:$GPRMC,161212.6,A,4653.89701,N,01940.55677,E,000.01,000.0,100913,004.3,E*5C
181225.293265920:$GPGGA,161212.6,4653.89701,N,01940.55677,E,2,08,1.4,124.2,M,41.3,M,,*59
181225.297247457:$GPGSA,A,3,,03,06,,14,18,19,22,27,32,,,2.0,1.4,1.5*34
181225.300419979:$GPVTG,000.0,T,355.7,M,000.01,N,0000.02,K*79
181225.303577147:$GPRMC,161212.8,A,4653.89701,N,01940.55677,E,000.01,000.0,100913,004.3,E*52
181225.306632425:$GPGGA,161212.8,4653.89701,N,01940.55677,E,2,08,1.4,124.2,M,41.3,M,,*57
181225.310040084:$GPGSA,A,3,,03,06,,14,18,19,22,27,32,,,2.0,1.4,1.5*34
181225.313133946:$GPVTG,000.0,T,355.7,M,000.01,N,0000.01,K*7A
181225.317166965:$GPRMC,161213.0,A,4653.89701,N,01940.55677,E,000.01,000.0,100913,004.3,E*5B
181225.320426880:$GPGGA,161213.0,4653.89701,N,01940.55677,E,2,08,1.4,124.2,M,41.3,M,,*5E
181225.323792082:$GPGSA,A,3,,03,06,,14,18,19,22,27,32,,,2.0,1.4,1.5*34
181225.327003400:$GPVTG,000.0,T,355.7,M,000.01,N,0000.01,K*7A
181225.330192100:$GPRMC,161213.2,A,4653.89701,N,01940.55677,E,000.01,000.0,100913,004.3,E*59
181225.333141314:$GPGGA,161213.2,4653.89701,N,01940.55677,E,2,08,1.4,124.2,M,41.3,M,,*5C
181225.336206449:$GPGSA,A,3,,03,06,,14,18,19,22,27,32,,,2.0,1.4,1.5*34
181225.339610415:$GPVTG,000.0,T,355.7,M,000.01,N,0000.02,K*79
181225.342976480:$GPRMC,161213.4,A,4653.89701,N,01940.55678,E,000.01,000.0,100913,004.3,E*50
181225.346003737:$GPGGA,161213.4,4653.89701,N,01940.55678,E,2,08,1.4,124.2,M,41.3,M,,*55
181225.349040725:$GPGSA,A,3,,03,06,,14,18,19,22,27,32,,,2.0,1.4,1.5*34
181225.352282572:$GPVTG,000.0,T,355.7,M,000.01,N,0000.02,K*79
181225.355736225:$GPRMC,161213.6,A,4653.89700,N,01940.55678,E,000.01,000.0,100913,004.3,E*53
181225.359730217:$GPGGA,161213.6,4653.89700,N,01940.55678,E,2,08,1.4,124.2,M,41.3,M,,*56
181225.363299063:$GPGSA,A,3,,03,06,,14,18,19,22,27,32,,,2.0,1.4,1.5*34
181225.366588198:$GPVTG,000.0,T,355.7,M,000.01,N,0000.02,K*79
181225.371109954:$GPRMC,161213.8,A,4653.89700,N,01940.55678,E,000.01,000.0,100913,004.3,E*5D
181225.374346102:$GPGGA,161213.8,4653.89700,N,01940.55678,E,2,08,1.4,124.2,M,41.3,M,,*58
181225.377370616:$GPGSA,A,3,,03,06,,14,18,19,22,27,32,,,2.0,1.4,1.5*34
181225.380446435:$GPVTG,000.0,T,355.7,M,000.01,N,0000.02,K*79

A linha $GPVTG contém a velocidade do veículo entre dois asteriscos ( os asteriscos não estão no arquivo ). A linha $GPGGA contém o tempo que também está entre dois asteriscos. Os dois primeiros caracteres são a hora, os próximos dois são minutos e os últimos dois são segundos.

O veículo é parado quando a velocidade é 0000. Eu preciso do tempo da primeira e última parada para que eu possa mudá-la para segundos e escrever para log.txt .

Eu posso fazer a alteração e a redação, mas preciso de ajuda para encontrar os horários das primeiras e últimas paradas do veículo.

Este é o meu arquivo run.sh:

#!/bin/bash
fullfilename=$1
filename=$(basename "$fullfilename")
ext="${filename##*.}"

if [[ $# -ne 1 ]]; then
  echo "Error 1"
  exit 1
elif [[ $ext != "log" ]]; then
  echo "Error 2"
  exit 1
elif [[ ! -r $fullfilename ]]; then
  echo "Error 3"
  exit 1
else
  grep '$GPGGA' $1 > test1.txt
  grep '$GPVTG' $1 > test2.txt
  cut -c50-53 test2.txt > speed.txt
  cat speed.txt | wc -l > dealer.txt
  while read line
    do
      I=0; for N in $(cat speed.txt); do I=$(($I + 10#$N)); done;
      echo "average speed:" $(($I / $line)) >> log.txt
  done < dealer.txt
  grep '0000' speed.txt | wc -l > stop.txt
  while read stop
    do
      echo "number of stops:" $stop >> log.txt
  done < stop.txt
fi

Já calculei a velocidade média e o número de paradas.

Nota: Sou novato no bash, por isso a minha solução não é a melhor para esta tarefa, mas não quero usar o awk até ter aprendido outros utilitários bash.

    
por bozsi12 23.04.2017 / 11:53

2 respostas

3

Do seu exemplo:

$ sed -nr '/0000/N;N; s/.*GPGGA,([^,]+).*//p' file | sed -n '1p;$p'
161212.2
161213.8

Notas

  • -n não imprime nada até pedirmos
  • -r use ERE
  • /0000/N;N encontra uma linha com 0000 e lê as próximas duas linhas
  • s/old/new replace old com new
  • .* quaisquer caracteres na linha
  • ([^,]+) salva alguns caracteres que não são , nessa posição
  • backreference para o padrão salvo
  • | passando a saída para outro sed (sem graça)
  • '1p;$p' imprima a linha 1 e imprima a última linha

E convertendo para segundos eu deixo para você ...

    
por Zanna 23.04.2017 / 13:04
2

Eu usaria awk para algo assim.

A ideia seria dividir os registros (linhas) em campos separados por vírgula e, em seguida:

  • se o primeiro campo terminar em $GPVTG e o oitavo campo começar com 0000 , defina um sinalizador booleano para indicar que o veículo está parado
  • quando o primeiro campo termina em $GPGGA e o veículo está parado, salve o valor da distância do segundo campo
  • no final, imprima os valores da primeira e da última distância

Então

#!/usr/bin/awk -f

function printsecs(s) { 
  print substr(s,5) + 60 * (substr(s,3,2) + 60 * substr(s,1,2));
}

BEGIN {FS=","}

$1 ~ /\$GPVTG$/ && $8 ~ /^0000/ {
  stopped = 1;
} 

$1 ~ /\$GPGGA$/ && stopped {
  t[++n] = $2; 
  stopped = 0; 
} 

END {
  printsecs(t[1]); printsecs(t[n]);
}
    
por steeldriver 24.04.2017 / 00:42