为什么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", }')
但是当我尝试使用 cat 和 awk 将它插入到上面的行中时,它会转换回普通整数。
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
这可能是一个关于 awk 处理 指数 的非常基本的问题。
我的输入行是:
1.047788047990001417e+02 2.931134551062188009e+01 3.669999999999999929e+00
我想在第三个位置添加-1000,但是是指数格式,所以首先我转换格式。
dept=$(echo -1000 | awk '{printf "%.7e\n", }')
但是当我尝试使用 cat 和 awk 将它插入到上面的行中时,它会转换回普通整数。
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