在jq中,如何获得tonumber输出小数而不是科学记数法

时间:2018-03-26 23:20:47

标签: json string decimal jq scientific-notation

在JSON对象中,给定字符串"0.0000086900"作为键值对的值,如果我对此|tonumber,则返回8.69e-06

如何确保只返回小数? 在上面的情况中,这将是0.0000086900

解决方案(基于匹配下面的Peak代码段)

def to_decimal:
  def rpad(n): if (n > length) then . + ((n - length) * "0") else . end;
  def lpad(n): if (n > length) then ((n - length) * "0") + . else . end;

tostring
  | . as $s
  | [match( "(?<sgn>[+-]?)(?<left>[0-9]*)(?<p>\\.?)(?<right>[0-9]*)(?<e>[Ee]?)(?<exp>[+-]?[0-9]+)" )
      .captures[].string] as [$sgn, $left, $p, $right, $e, $exp]
  | if $e == "" then .
    else ($exp|tonumber) as $exp
    | ($left|length) as $len
    | if $exp < 0 then "0." + ($left | lpad(1 - $exp - $len)) + $right
      else ($left | rpad($exp - $len)) + "." + $right
      end
      | $sgn + .
    end;

1 个答案:

答案 0 :(得分:1)

不幸的是,目前jq中没有办法修改JSON数字的表示形式;最好的方法是将其表示形式修改为字符串。以下是可以做什么的简单说明。

to_decimal将JSON号(或数字的有效JSON字符串表示)作为输入作为输入,并将其转换为合适的字符串,例如:

(0.0e6, 1, -1, .123e3, -0.123e+3, 1.23e-6, 1.23e6)
| to_decimal    

产生

"0"
"1"
"-1"
"123"
"-123"
".00000123"
"1230000"

to_decimal

def to_decimal:
  def rpad(n): if (n > length) then . + ((n - length) * "0") else . end;
  def lpad(n): if (n > length) then ((n - length) * "0") + . else . end;
  tostring
  | . as $s
  | capture( "(?<sgn>[+-]?)(?<left>[0-9]*)(?<p>\\.?)(?<right>[0-9]*)(?<e>[Ee]?)(?<exp>[+-]?[0-9]+)" )
  | if .e == "" then $s
    else (.left|length) as $len
    | (.exp | tonumber) as $exp
    | if $exp < 0 then .sgn + "." + (.left | lpad(1 - $exp - $len)) + .right
      else .sgn + (.left | rpad($exp - $len)) + "." + .right
      end
    end ;