Home > OS >  Why awk convert exponential to normal integar?
Why awk convert exponential to normal integar?

Time:04-13

This may be a very basic question about awk to handle exponential.

My input line is:

1.047788047990001417e 02 2.931134551062188009e 01 3.669999999999999929e 00

I want to add -1000 at third position but in exponential format, so first I convert the format.

dept=$(echo -1000 | awk '{printf "%.7e\n", $1}')

But when I try to insert it into the above line using cat and awk, it converts back to normal integers.

cat $line | awk '{print $1 ,$2 ,'$dept', $3}'

I got this output:

1.048020560949027811e 02 2.976214868620721887e 01 -1000 6.065999999999999837e 00

May you please indicate that where I am doing something wrong or how I can correct it? Besides this, is there any option to limit the 7 decimal numbers before e?

For example ideally expected output should be like this:

1.0480205e 02 2.9762148e 01 -1.0000000e 03 6.0659999e 00

CodePudding user response:

Integers are printed as integers by default, even if you input it with exponential notation. If you want it formated, use printf().

cat "$line" | awk -v dept=-1.0000000e 03 '{printf("%e %e %e %e\n", $1, $2, dept, $3)}'

Use the -v option to turn a shell variable into an awk variable, rather than substituting the variable into the awk script.

CodePudding user response:

The culprit is this line in bash (not awk yet):

cat $line | awk '{print $1 ,$2 ,'$dept', $3}'

Bash replaces the values in the unquoted parts of the line:

awk '{print $1 ,$2 ,'-1.0000000e 03', $3}'

then removes the quotes, and recognises "words":

$0=awk
$1={print $1 ,$2 ,-1.0000000e 03, $3}

Now you can see that awk treats -1.0000000e 03 as a number, and it is not aware that there is any particular format it should stick to; it figures -1000 is the easier way to represent that number and prints that.

To avoid that, you have to tell awk to treat $dept as a string — by including some extra quoting:

cat $line | awk '{print $1 ,$2 ,"'$dept'", $3}'

EDIT: This answer tells you exactly what is going on in your code; but you should use Barmar's answer, as it is much cleaner way to do what you want.

CodePudding user response:

you mean like this ?

echo '1.047788047990001417e 02
      2.931134551062188009e 01
      3.669999999999999929e 00' \
 \
 | mawk 'NF =($_=sprintf("%.*e %.*e %.*e %.*e",
                 __=-(  _) (  _^  _),$(_ =-_  ),__,
                    $  _,__,-(  _ __)^_,__,$_))~""'

1.0477880e 02 2.9311346e 01 -1.0000000e 03 3.6700000e 00
  • Related