在Bash中将科学计数法转换为十进制

8

我想将科学计数法表示的数字转换为浮点数,以便对数据执行一些比较操作。该操作是在bash脚本中完成的 - 下面是一小段代码:

while read track_id landfall_num gate_id pres_inter
do
  if [[ $landfall_num == 0001 ]]
  then
     start_flag = true
     echo DING DING $start_flag
     if [[ $pres_inter < 97000 ]]
     then
        echo Strong Storm From North $track_id, $gate_id, $pres_inter
     fi
  fi
done < $file

我的问题是,当我使用<时,我的<操作符基本上选择了所有存储在科学计数法中的压力值,而当我使用>时,则没有选择。我正在观察以帕斯卡为单位的大气压测量结果,而不是毫巴。
以下是示例输出:
Strong Storm From North 0039988 0017 1.0074E+05

Strong Storm From North 0037481 0018 9.9831E+04

这两场风暴都不应满足选择标准!


为什么不使用 Perl 的一行命令呢? - Brian Vandenberg
3个回答

9

我认为使用awk是最好的方法。例如,在数字“1.0074E + 05”的情况下:

echo“1.0074E + 05”| awk-F“E”'BEGIN {OFMT =“%10.10f”} {print $ 1 *(10 ^ $ 2)} '

输出结果为:

100740.0000000000

显然,您可以使用小于10位小数的精度:)


1
这应该是被接受的答案。简洁明了。对负数也适用。现在我可以在我的终端上看到SHIB的价格 :) - Noah Gary

8

首先,Bash无法使用浮点数进行算术运算。其次,即使对于整数,Bash也不知道科学计数法。

如果您绝对确定所有数字都是整数,那么可以尝试的第一件事是将它们转换为十进制表示形式:printf可以轻松完成这项工作:

printf -v pres_inter "%.f" "$pres_inter"

(%.f 四舍五入到最接近的整数)。

然后使用bash的算术运算:

if (( pres_inter < 97000 )); then ....

这个解决方案很棒,不使用任何外部命令或子shell:速度和效率!现在如果你处理的是非整数,最好使用bc进行算术运算:但由于bc无法很好地处理科学计数法,所以你必须将数字转换为十进制表示法。因此,类似以下内容应该可以解决问题:
printf -v pres_inter "%f" "$pres_inter"
if (( $(bc -l <<< "$pres_inter<97000") )); then ...

当然,这会比较慢,因为你在分叉一个 bc。如果你对整数满意的话,只需坚持我给出的第一种可能性就可以了。
完成!

2

在进行数字比较时,您需要使用以下命令:

  • -eq 代替 ==
  • -ne 代替 !=
  • -lt 代替 <
  • -le 代替 <=
  • -gt 代替 >
  • -ge 代替 >=

同时,为了解决一些语法问题:

while read track_id landfall_num gate_id pres_inter
do
  landfall_num=$(printf "%f", "$landfall_num")
  if [[ "$landfall_num" -eq 1 ]]
  then
     start_flag="true"
     echo "DING DING $start_flag"
     if [[ "$pres_inter" -lt 97000 ]]
     then
        echo "Strong Storm From North $track_id, $gate_id, $pres_inter"
     fi
  fi
done < "$file"

更新:

以下是如何将科学计数法数字转换为整数的方法:

printf "%.0f\n", 1.0062E+05

例如,输出:
100620

所以:

landfall_num=$(printf "%f", "$landfall_num")

将会把landfall_num从科学计数法转换成普通的十进制整数。


谢谢。只是好奇 - 上周我刚上了一个shell编程课,他们没有讲解所有的引号。为什么您认为这是更好的语法?谢谢! - kimmyjo221
通常最好将变量用双引号括起来,以消除一些边缘情况,例如空字符串或包含换行符的字符串。 - sampson-chen
除非与其他类型的测试组合使用更清晰,否则不要使用[[进行算术比较。通常,使用(())进行算术运算。Bash无法处理浮点数,因此任何一种方法都无法工作。 - ormaaj
@kimmyjo221 这是因为科学计数法尚未转换。Bash本身不支持浮点数比较,如果整数可以的话,请参见更新的答案。 - sampson-chen
这不是使用“-lt”与“<”的问题,而是科学计数法的问题...你的代码行if [[ "$pres_inter" -lt 97000 ]]将会失败。 - gniourf_gniourf
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接