¿Cómo encontrar la diferencia entre dos marcas de time hasta milisegundos?

Soy nuevo en shell scripting. El corazón de mi script es encontrar la diferencia entre dos marcas de time hasta milisegundos. Conmigo tengo un file con contenido de marcas de time solo como

2012-09-13 15:00:29,290 2012-09-13 15:00:29,297 2012-09-13 15:00:29,428 2012-09-13 15:00:29,447 

Así tengo alnetworkingedor de 30k loggings, donde no debería enfrentar ningún problema de performance cuando ejecuto el script. Muchos factores como el año bisiesto, los meses con 31 días, etc. entran en escena cuando bash escribir guiones para esto.

¿Alguien puede ayudarme en esto por favor?

No es necesario hacer un análisis complejo, la date hará toda la magia por ti, con la ayuda de su amigo, bash :

 #!/bin/bash while read d1_1 d1_2 d2_1 d2_2; do secdiff=$(( $(date -d "$d2_1 $d2_2" +%s) - $(date -d "$d1_1 $d1_2" +%s) )) nanosecdiff=$(( $(date -d "$d2_1 $d2_2" +%N) - $(date -d "$d1_1 $d1_2" +%N) )) printf "%s %s - %s %s = %d milliseconds\n" $d2_1 $d2_2 $d1_1 $d1_2 $(( (secdiff * 1000) + (nanosecdiff / 1000000) )) done < YOUR_FILE.txt 

SALIDA

 2012-09-13 15:00:29,297 - 2012-09-13 15:00:29,290 = 7 milliseconds 2012-09-13 15:00:29,447 - 2012-09-13 15:00:29,428 = 19 milliseconds 

Ver man date

NOTA

  • date -d es muy útil, convierte las marcas de time
  • %s es el time de época (segundos desde 01-01-1970)
  • %N es nanosegundos
  • $(( )) y (( )) son para la aritmética de bash , ver http://mywiki.wooledge.org/ArithmeticExpression
  • $( ) representa command substitution

¿Esto también se adapta a tus necesidades?

Un lenguaje de scripting como Perl, Python o Ruby será rápido y requerirá poco esfuerzo. Por ejemplo, con Perl y Date :: Parse :

 perl -MDate::Parse -l -ne 's/,/./g; split; print str2time("$_[2] $_[3]") - str2time("$_[0] $_[1]")' 

(Para cada línea, reemplace , por . , Divida la línea en palabras $_[0] a $_[3] , analice las dates formadas por las dos primeras y las siguientes dos palabras, e imprima la diferencia).

Acabo de encontrar esta publicación, hay, al less hoy, una solución basada en la date más simple. Usando el marco en la respuesta de @Gilles Quenot (habría escrito un comentario a su abogado, pero no la reputación suficiente):

 while read d1_1 d1_2 d2_1 d2_2 do date -d "$d2_1 $d2_2 $(date -d "$d1_1 $d1_2" +%s.%N) seconds ago" +%s.%N done << END 2012-09-13 15:00:29,290 2012-09-13 15:00:29,297 END 

El resultado:

 $ ./time_elapsed.sh 0.007000000 

Usar %3N lugar de %N truncará la salida a milisegundos.