问题
In a JSON object, given the string "0.0000086900"
as the value of a key-value pair, if I do |tonumber
on this, 8.69e-06
gets returned.
How can I ensure that only decimals are ever returned?
In the case above, this would be 0.0000086900
SOLUTION (based on Peak's code snippet below)
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:
Unfortunately there is currently no way in jq to modify the representation of JSON numbers as such; the best one can do is modify their representation as strings. Here is a simple illustration of what can be done.
to_decimal
takes as input a JSON number (or a valid JSON string representation of a number, possibly with a leading "+") as input, and converts it into a suitable string, e.g.:
["0","1","-1","123","-123",".00000123","1230000","-.00000123","-0.123","0.123","0.001"]
produces:
[0,"0"]
["+1","1"]
[-1,"-1"]
[123,"123"]
[-123,"-123"]
[1.23e-06,".00000123"]
[1230000,"1230000"]
[-1.23e-06,"-.00000123"]
[-0.123,"-0.123"]
[0.123,"0.123"]
[0.001,"0.001"]
Notice that any leading "+" is dropped.
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 (if .sgn == "+" then $s[1:] else $s end)
else (.left|length) as $len
| (.exp|tonumber) as $exp
| (if .sgn == "-" then "-" else "" end ) as $sgn
| if $exp < 0 then "." + (.left | lpad(1 - $exp - $len)) + .right
else (.left | rpad($exp - $len)) + "." + .right
end
| $sgn + .
end ;
来源:https://stackoverflow.com/questions/49502120/in-jq-how-to-get-tonumber-to-output-decimal-instead-of-scientific-notation