user3630156
user3630156

Reputation: 21

Awk is converting 'nan' to zeros

I am attempting to preserve the 'nan's in an array of geophysical data. I am using the following code as part of a linux string:

awk 'NR>50 {printf "(%d, %d, %d) %f %f %f %F\n",$1,$2,$3*10000,$4,$5,$7,$6}'<$PST 

Why are the nan's getting converted to zeros? How can I preserve the nan's in the original data? I was told that it might have something to do with the lower-case letters of nan, as opposed to NAN or NaN?

Upvotes: 2

Views: 1968

Answers (3)

Ed Morton
Ed Morton

Reputation: 203712

The word "NaN" is just a string like any other string. Treating it as anything else breaks historical awk script functionality.

Can you add a sign in front of it so gawk knows it's a number rather than a string?

$ gawk 'BEGIN{n="NaN";printf "%d : %f : %s\n",n,n,n}'
0 : 0.000000 : NaN

$ gawk 'BEGIN{n="+NaN";printf "%d : %f : %s\n",n,n,n}'
nan : nan : +NaN

$ gawk 'BEGIN{n="-NaN";printf "%d : %f : %s\n",n,n,n}'
nan : nan : -NaN

Alternatively, using the -M option (see http://www.gnu.org/software/gawk/manual/gawk.html#Gawk-and-MPFR) may be what you want:

$ gawk -M 'BEGIN{n="NaN";printf "%d : %f : %s\n",n,n,n}'
nan : nan : NaN

You could use --posix if all else fails, but that disables all of the very useful gawk-specific functionality (e.g. gensub()) so it's best avoided.

Upvotes: 1

ojs
ojs

Reputation: 502

Using the posix version with gawk should work (following Kent's example)

gawk --posix 'BEGIN{n="NaN";printf "%d : %f : %s\n",n,n,n}'

prints out

nan : nan : NaN

Upvotes: 1

Kent
Kent

Reputation: 195129

in awk, if we do math calculation on a Nan string, the string will be converted into zero, also for printf. see example:

kent$  awk 'BEGIN{n="nan";printf "%d : %f : %s\n",n,n,n}'
0 : 0.000000 : nan

If you want to use printf, you need to define the format (%s or %d/%f) dynamically up to the $1 ,$2 .... You can either check with regex, e.g. "^[0-9.]+$" (it is not very strict to check number, just as example) or compare to the nan like tolower($1)=="nan".

you can also consider to first build the string (with checkings), then print it all at the end.

Upvotes: 2

Related Questions