我想从我的 wifi 设备获取数据使用情况以显示在我的顶部栏上,我可以使用这样的curl 获取数据使用情况(以字节为单位)
$bytes=(curl -d "Page=GetWANInfo" -X POST http://jiofi.local.html/cgi-bin/qcmap_web_cgi -s| jq -r .total_data_used)
它给了我一个很大的数字,就像411982397
现在我想将其转换为 MB 并希望将其显示为411.9 MB
但我不知道如何才能像这样格式化这么大的数字。
我尝试使用bc
将其转换为MBecho $bytes / 1000000 | bc
但我无法将其放入变量中,这给了我错误。
$ total=($bytes / 1000000 | bc)
bash: syntax error near unexpected token `|'
$ total=$($bytes / 1000000 | bc)
411982397: command not found
$ echo "$bytes / 1000000" | bc
411
$ total=$("$bytes / 1000000" | bc)
bash: 411982397 / 1000000: No such file or directory
我的想法是将输出放入一个变量中,而不是我可以的echo $total MB
解决这个问题的更好方法是什么?我还需要每隔几秒运行一次这个命令,所以我需要一个有效的解决方案来解决这个问题,这个问题很容易被CPU占用
答案1
jq
可以做除法:
$ echo '{"total_data_used":411982397}' | jq -r '.total_data_used/1e6|tostring + "MB"'
411.982397MB
如果您不必专门使用 bash,大多数现代 shell(至少是 zsh、ksh93、yash、fish)也可以自行完成此操作。
在 zsh 中:
printf -v total %gMB $(( bytes / 1_000_000. ))
(注意.
强制浮点运算。您也可以使用1e6
)。
ksh93printf
还内置支持转换为带有 kMGTPE 后缀的人类可读格式,均使用基于 1000 的单位和 1024 单位:
$ printf '%#dB\n' bytes
412MB
$ printf '%#iB\n' bytes
393MiB
具体来说,在 bash 中,对于除以 10 的幂的特殊情况,您可以printf
通过附加e-6
到整数并将其用作%e
、%f
、%g
、%a
(或大写变体)的参数来使用它。
printf -v total %gMB "${bytes}e-6"
默认精度为%g
6 位有效数字,如果您愿意,可以更改该精度,%.12g
例如 12 位数字。请注意printf
(至少在 bash 和 zsh 中)遵循区域设置的十进制基数字符。例如,您将在英语区域设置中获得 411.982MB,在法语/德语区域设置中获得 411,982MB。
要bc
进行除法,您需要在其标准输入上提供表达式,方法是通过管道传输输出它的命令的输出(通常printf
用于此操作),或者使用此处文档(标准sh
)或此处-string(来自 zsh,但现在在许多其他 shell 中都可以找到),然后使用命令替换通过管道获取其输出,例如存储到变量中total
。
但是你需要设置它的scale
特殊变量,告诉它除法时要计算基数后的位数(默认为 0,除非-l
使用该选项,在这种情况下它是 20)。所以:
total=$(
printf 'scale=2\n%d / 1000000\n' "$bytes" | bc
)
或者:
total=$(
bc << EOF
scale=2
$bytes / 1000000
EOF
)
另一种方法bc
是awk
它可以进行浮点运算并用它自己的格式格式化数字printf
:
total=$(
jq... | awk '{printf "%gMB", $0 / 1e6}'
)
1echo
也很常用,但是由于它具有不可移植且不可靠的 API,因此在一般情况下最好避免输出任意数据
答案2
我想你正在寻找total=$(echo "$bytes / 1000000 " | bc)
。