为什么 awk 将指数转换为普通整数?

问题描述 投票:0回答:3

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

我的输入行是:

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

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

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

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

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

我得到了这个输出:

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
3个回答
4
投票

默认情况下,即使您使用指数表示法输入整数,也会将其打印为整数。如果您想要格式化,请使用

printf()

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

使用

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


1
投票

罪魁祸首是

bash
中的这一行(还不是
awk
):

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

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

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

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

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

现在您可以看到

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

为了避免这种情况,您必须告诉

awk
$dept
视为字符串 - 通过包含一些额外的引号:

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

编辑:这个答案准确地告诉您代码中发生了什么;但你应该使用 Barmar 的答案,因为这是做你想做的事情的更干净的方式。


0
投票

你的意思是这样吗?

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
© www.soinside.com 2019 - 2024. All rights reserved.