为什么awk将指数转换为正常整数?

Why awk convert exponential to normal integar?

这可能是一个关于 awk 处理 指数 的非常基本的问题。

我的输入行是:

1.047788047990001417e+02 2.931134551062188009e+01 3.669999999999999929e+00

我想在第三个位置添加-1000,但是是指数格式,所以首先我转换格式。

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

但是当我尝试使用 catawk 将它插入到上面的行中时,它会转换回普通整数。

cat $line | awk '{print  , ,'$dept', }'

我得到了这个输出:

1.048020560949027811e+02 2.976214868620721887e+01 -1000 6.065999999999999837e+00

能否指出我哪里做错了或者我该如何改正? 除此之外,是否有任何选项可以限制e之前的7位小数?

例如理想情况下预期的输出应该是这样的:

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

罪魁祸首是 bash 中的这一行(还不是 awk):

cat $line | awk '{print  , ,'$dept', }'

Bash 替换行中未加引号的部分中的值:

awk '{print  , ,'-1.0000000e+03', }'

然后删除引号,并识别“单词”:

[=12=]=awk
={print  , ,-1.0000000e+03, }

现在您可以看到 awk-1.0000000e+03 视为一个数字,并且不知道它应该遵循任何特定格式;它认为 -1000 是表示该数字并打印该数字的更简单方法。

为避免这种情况,您必须告诉 awk$dept 视为字符串——通过包含一些额外的引号:

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

编辑:这个答案告诉你代码中到底发生了什么;但你应该使用 Barmar 的答案,因为它是做你想做的事情的更简洁的方法。

默认情况下,整数将打印为整数,即使您使用指数表示法输入也是如此。如果要格式化,请使用 printf().

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

使用 -v 选项将 shell 变量转换为 awk 变量,而不是将变量替换到 awk 脚本中。

你的意思是这样的?

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