Comment prendre la valeur absolue en utilisant awk?

14

Si j'ai moins de deux dates:

2015-09-12,2015-08-13

Et j'ai besoin d'obtenir le nombre de jours entre eux, j'utiliserai le code ci-dessous:

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

La sortie de ce code sera alors -29que la différence est29

Eng7
la source

Réponses:

23

Vous pouvez définir des fonctions awkcomme:

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

L'astuce courante pour ce genre de situations est d'utiliser la racine carrée du carré:

awk -F'[-,]' '{print sqrt((360*($4-$1)+30*($5-$2)+($6-$3))^2)}'
jimmij
la source
3
Un peu exagéré cependant. Notez que sqrt(x^2)c'est bien, mais sqrt(x)^2peut introduire de minuscules erreurs qui peuvent provoquer des surprises. Pour busybox awk, il doit être construit avec le support mathématique activé (pas la valeur par défaut dans les paquets Debian par exemple).
Stéphane Chazelas
3
Sqrt (x) ^ 2 n'échouerait-il pas simplement pour les nombres négatifs?
Daniel McLaury
1
@DanielMcLaury C'est pourquoi c'est le cas sqrt(x^2).
jimmij
@jimmij: Je réponds au commentaire de votre réponse, pas à la réponse elle-même.
Daniel McLaury
3

Autrement:

awk -F'[-,]' '{d=360*($4-$1)+30*($5-$2)+($6-$3);print (d>0)?d:-d}'
cuonglm
la source
C'est probablement la réponse (la performance) la plus efficace.
Hastur
2

En supposant que vous êtes sur GNU awk, la mktimefonction funky est utile ici.

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
la source
1

Trop tard, mais voici une solution utilisant la datecommande GNU qui n'est pas basée sur 30 jours fixes chaque mois que toutes les réponses postées ci-dessus la considéraient comme la réponse 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

Pour l'entrée ci-dessous:

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

La sortie est:

30
28
αғsнιη
la source