¿Cómo tomar el valor absoluto usando awk?


14

Si tengo a continuación dos fechas:

2015-09-12,2015-08-13

Y necesito obtener el número de días entre ellos, usaré el siguiente código:

awk -F'[-,]' '{print 360*($4-$1)+30*($5-$2)+($6-$3)}'

La salida para este código será -29mientras que en realidad la diferencia es29

Respuestas:


23

Puede definir funciones awkcomo:

awk -F'[-,]' '
  function abs(v) {return v < 0 ? -v : v}
  {print abs(360*($4-$1)+30*($5-$2)+($6-$3))}'

11

El truco común para este tipo de situaciones es usar la raíz cuadrada del cuadrado:

awk -F'[-,]' '{print sqrt((360*($4-$1)+30*($5-$2)+($6-$3))^2)}'

3
Aunque un poco exagerado. Tenga en cuenta que sqrt(x^2)está bien, pero sqrt(x)^2puede introducir pequeños errores que pueden causar sorpresas. Para busybox awk, debe construirse con soporte matemático habilitado (no el predeterminado en los paquetes Debian, por ejemplo).
Stéphane Chazelas

3
¿No fallaría sqrt (x) ^ 2 simplemente para números negativos?
Daniel McLaury

1
@DanielMcLaury Por eso es así sqrt(x^2).
jimmij

@ jimmij: estoy respondiendo al comentario sobre tu respuesta, no a la respuesta en sí.
Daniel McLaury

3

De otra manera:

awk -F'[-,]' '{d=360*($4-$1)+30*($5-$2)+($6-$3);print (d>0)?d:-d}'

Esta es probablemente la respuesta más eficiente (rendimiento).
Hastur

2

Suponiendo que esté en GNU awk, la mktimefunción funky resulta útil aquí.

awk -F, '{ gsub(/-/," ",$0);a=(mktime($2 " 23 59 59")-mktime($1 " 00 00 00"))/86400;print a*(a<0?-1:1)}' file.txt
29

1

Demasiado tarde, pero aquí hay una solución que usa el datecomando GNU que no se basa en 30 días fijos cada mes que todas las respuestas publicadas anteriormente lo consideraron como la respuesta de Steve .

awk -F, '{cmd="printf \"%d\n\" $((($(date -d"$1" +%s)-$(date -d"$2" +%s))/86400))"; 
    cmd|getline $0; $0*=($0<0?-1:1); close(cmd)}1' infile

Para la entrada a continuación:

2015-09-12,2015-08-13
2017-02-12,2017-03-12

El resultado es:

30
28
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.