valerio
valerio

Reputation: 717

Arithmetic operations with awk

I am trying to use awk to modify the first column of this file:

0.947250   0.000000 0.001000 0.015500 0.177000 0.806500
0.971700   0.000000 0.000100 0.005000 0.102900 0.892000
0.985701   0.000000 0.000000 0.001200 0.054795 0.944006
0.994251   0.000000 0.000000 0.000000 0.022998 0.977002
0.996850   0.000000 0.000000 0.000000 0.012599 0.987401
0.998150   0.000000 0.000000 0.000000 0.007399 0.992601
0.998800   0.000000 0.000000 0.000000 0.004800 0.995200
0.999250   0.000000 0.000000 0.000000 0.003000 0.997000
0.999450   0.000000 0.000000 0.000000 0.002200 0.997800
0.999750   0.000000 0.000000 0.000000 0.001000 0.999000

I would need to transform the values in the first column in 1-value, leaving the other columns unchanged. I am trying the command

awk '{ x=1.-$1; print x,$2,$3,$4,$5,$6}' in_file > out_file

but this gives me

1  0.000000 0.001000 0.015500 0.177000 0.806500
1  0.000000 0.000100 0.005000 0.102900 0.892000
1  0.000000 0.000000 0.001200 0.054795 0.944006
1  0.000000 0.000000 0.000000 0.022998 0.977002
1  0.000000 0.000000 0.000000 0.012599 0.987401
1  0.000000 0.000000 0.000000 0.007399 0.992601
1  0.000000 0.000000 0.000000 0.004800 0.995200
1  0.000000 0.000000 0.000000 0.003000 0.997000
1  0.000000 0.000000 0.000000 0.002200 0.997800
1  0.000000 0.000000 0.000000 0.001000 0.999000

What am I doing wrong?

I've also tried different statements, but none worked. Here's a screenshot:

enter image description here

Update

Looks like the problem was with my version of awk (I am using awk version 20070501 on OSX 10.9.5) and not with the syntax. In fact, I downloaded gawk and now everything seems to be fine. So the question should maybe be why my awk seems to not be working correctly...

Upvotes: 1

Views: 429

Answers (4)

Ed Morton
Ed Morton

Reputation: 203502

Your awk is behaving correctly, the problem is your locale setting which currently is using , instead of . as the decimal point and that contradicts your data so the string 0.5 will be treated as 0 in numerical operations since the intended number would have been 0,5.

Use:

LC_ALL=C awk '{$1=1-$1}1' in_file > out_file

instead (or export LC_ALL=C in your environment to use that setting for all commands) and see https://unix.stackexchange.com/a/87763/133219 for information on locales and LC_ALL.

Upvotes: 0

Thomas Dickey
Thomas Dickey

Reputation: 54515

Agreeing with comments that locale is a likely culprit, OP could be using any of various locales where "." is not a decimal separator. For instance,

LC_ALL=it_IT.UTF-8 ./foo.sh;cat out_file

gives me (same version of BSD-awk):

1 0.000000 0.001000 0.015500 0.177000 0.806500
1 0.000000 0.000100 0.005000 0.102900 0.892000
1 0.000000 0.000000 0.001200 0.054795 0.944006
1 0.000000 0.000000 0.000000 0.022998 0.977002
1 0.000000 0.000000 0.000000 0.012599 0.987401
1 0.000000 0.000000 0.000000 0.007399 0.992601
1 0.000000 0.000000 0.000000 0.004800 0.995200
1 0.000000 0.000000 0.000000 0.003000 0.997000
1 0.000000 0.000000 0.000000 0.002200 0.997800
1 0.000000 0.000000 0.000000 0.001000 0.999000

while

LC_ALL=en_US.UTF-8 ./foo.sh;cat out_file

gives me

0.05275 0.000000 0.001000 0.015500 0.177000 0.806500
0.0283 0.000000 0.000100 0.005000 0.102900 0.892000
0.014299 0.000000 0.000000 0.001200 0.054795 0.944006
0.005749 0.000000 0.000000 0.000000 0.022998 0.977002
0.00315 0.000000 0.000000 0.000000 0.012599 0.987401
0.00185 0.000000 0.000000 0.000000 0.007399 0.992601
0.0012 0.000000 0.000000 0.000000 0.004800 0.995200
0.00075 0.000000 0.000000 0.000000 0.003000 0.997000
0.00055 0.000000 0.000000 0.000000 0.002200 0.997800
0.00025 0.000000 0.000000 0.000000 0.001000 0.999000

Further reading:

Upvotes: 0

sjsam
sjsam

Reputation: 21965

By default awk prints all the fields with the print command. Below would suffice :

awk '{$1=1-$1;print}' in_file > out_file

Edit : Based on [ @ed-morton's ] comment to [ this ] answer :

Sometimes awk can behave in an unexpected way if the locale is not C (or POSIX, which should be the same).

LC_ALL_OLD="$LC_ALL"
LC_ALL=C
awk '{$1=1-$1;print}' in_file > out_file
LC_ALL="$LC_ALL_OLD"

Reference

[ What does LC_ALL=C do? ]

Upvotes: 4

valerio
valerio

Reputation: 717

I solved the problem installing gawk on my mac (OSX 10.9.5). For some reason my awk implementation was not working correctly.

gawk '{ x=1.-$1; print x,$2,$3,$4,$5,$6}' in_file > out_file

The output is now correct:

0.05275 0.000000 0.001000 0.015500 0.177000 0.806500
0.0283 0.000000 0.000100 0.005000 0.102900 0.892000
0.014299 0.000000 0.000000 0.001200 0.054795 0.944006
0.005749 0.000000 0.000000 0.000000 0.022998 0.977002
0.00315 0.000000 0.000000 0.000000 0.012599 0.987401
0.00185 0.000000 0.000000 0.000000 0.007399 0.992601
0.0012 0.000000 0.000000 0.000000 0.004800 0.995200
0.00075 0.000000 0.000000 0.000000 0.003000 0.997000
0.00055 0.000000 0.000000 0.000000 0.002200 0.997800
0.00025 0.000000 0.000000 0.000000 0.001000 0.999000

Also with different statements:enter image description here

(Installing gawk on mac)

Upvotes: 0

Related Questions