jq中如何使tonumber返回小数而非科学计数法格式?
在jq中让tonumber输出小数格式而非科学计数法的解决方案
我之前也碰到过完全一样的需求——用tonumber处理"0.0000086900"这类字符串时,结果会变成8.69e-06这种科学计数法格式,但我们需要保留原有的小数形式。下面是基于Peak提供的代码片段优化后的完整解决方案:
自定义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 | if test("e|E") then match("(?<sgn>[+-]?)(?<int>\\d+)(?<exp>[eE][+-]\\d+)") | .captures | reduce .[] as $c ({}; . + {($c.name): $c.string}) | .exp |= ltrimstr("e") | .exp |= ltrimstr("E") | .int |= if .exp | tonumber < 0 then "0." + lpad(-(.exp | tonumber) - 1; "0") + .int else .int + rpad(.exp | tonumber; "0") + ".0" end | .sgn + .int else $s end;
使用示例
假设你有这样的JSON数据:
{"amount": "0.0000086900"}
执行以下jq命令:
jq '.amount | tonumber | to_decimal' your_file.json
输出结果就是:
"0.0000086900"
函数原理说明
- 先用
tostring把数字转换成字符串,方便后续文本处理 - 判断字符串是否包含科学计数法标记
e/E,如果是则通过正则捕获拆分出正负号、整数部分和指数部分 - 根据指数的正负做不同处理:指数为负时,在整数前补对应数量的零并添加小数点;指数为正时,在整数后补对应数量的零
- 最后拼接正负号和处理后的数字部分,得到标准的小数格式字符串
- 如果原本就不是科学计数法格式,直接返回原字符串
这样就能完美解决你遇到的问题,把科学计数法结果转换成你需要的小数形式啦~
内容的提问来源于stack exchange,提问作者John S.
相关产品推荐
相关产品推荐

