¿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

Eng7
fuente

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))}'
Stéphane Chazelas
fuente
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)}'
jimmij
fuente
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}'
Cuonglm
fuente
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
Steve
fuente
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
αғsнιη
fuente