无法将基本计算器的输出放入变量中,在 bash 中将字节格式化为 MB

无法将基本计算器的输出放入变量中,在 bash 中将字节格式化为 MB

我想从我的 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"

默认精度为%g6 位有效数字,如果您愿意,可以更改该精度,%.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
)

另一种方法bcawk它可以进行浮点运算并用它自己的格式格式化数字printf

total=$(
  jq... | awk '{printf "%gMB", $0 / 1e6}'
)

1echo也很常用,但是由于它具有不可移植且不可靠的 API,因此在一般情况下最好避免输出任意数据

答案2

我想你正在寻找total=$(echo "$bytes / 1000000 " | bc)

相关内容