对具有内存大小单位的值进行算术

对具有内存大小单位的值进行算术

假设我有一堆代表内存量的数字,以86k320m或的形式编写1.7g。如何在命令行中计算它们的总和,并返回人类可读的结果?

能够计算减法也很好。完美的工具可以处理多组符号(例如1g/ 1G/ 1GB/ 1Go/ 1GiB/ 1.7Gio)及其含义(二进制或十进制乘数)。

我正在寻找一个纯粹的计算器。这些数字不一定是我磁盘上某些文件的大小,因此不能选择findstat或等工具。du

这显然很容易实现(在精度方面存在一些障碍),但如果这还不存在,我会被诅咒的!

答案1

一点自我推销:我们写了一个名为的库库字节大小用 C 和 Python 进行这些计算,它还有一个名为的命令行工具计算

$ bscalc "5 * (100 GiB + 80 MiB) + 2 * (300 GiB + 15 GiB + 800 MiB)"
1215425413120 B
1186938880.00 KiB
   1159120.00 MiB
      1131.95 GiB
         1.11 TiB

该库已打包在大多数发行版中,但不幸的是该工具并未打包。它存在于 Fedoralibbytesize-tools和 SuSEbscalc软件包中,但不在 Debian/Ubuntu 中。

答案2

英卡

$ bcal -m "(5kib+2mib)/2"
1051136 B
$ bcal -m "(5kb+2mb)/2"
1002500 B

-m标志用于简短输出。删除它会详细输出以 2 为基数(KiB、MiB、GiB、TiB)和以 10 为基数(kB、MB、GB、TB)的结果。

它不理解86kor320m1.7g,毕竟这些不是正确的字节单位。在这种情况下,您可以使用 Sed 在每个字母后面添加b,然后通过管道将其传输到bcal

$ cat file
1.7g+320m+86k
$ sed 's/[gmk]/&b/g' file | bcal -m
bcal> 1.7gb+320mb+86kb
2020086000 B

您还可以在交互模式下使用它。

答案3

在 中zsh,您可以定义一个数学函数,例如:

() {
  typeset -gA bsuffix
  local n=1 ni=1 s
  for s (k m g t p e) {
    (( n *= 1000 )); (( ni *= 1024 ))
    (( bsuffix[$s] = bsuffix[${s}ib] = bsuffix[${s}io] = ni ))
    (( bsuffix[${s}b] = bsuffix[${s}o] = n ))
  }
}
b() {
  set -o localoptions -o extendedglob
  local s=${(M)1%(#i)(${(j:|:k)~bsuffix})}
  (( ${1%$s} * ${bsuffix[$s:l]-1} ))
}

functions -Ms b

然后您就可以在任何 zsh 算术表达式中使用b(1G), ,例如 in , ,等,或 in :b(1mB)(( .... ))$(( ... ))$array[...]zcalc

$ <<< $((b(86k) + b(320mb) + b(1.7gio)))
2145449164.8

$ autoload zcalc
$ zcalc
1> b(86k) + b(320mb) + b(1.7gio)
2.14545e+09
2> :sci 15
2145449164.8

$ echo $(( b(infeo) ))
Inf   

答案4

如何在命令行中计算它们的总和,并返回人类可读的结果?

Ksh 支持浮点数学,因此您可以在 .kshrc 中定义所需的常量并使用它们进行数学运算

然后得到人类可读的结果只需使用内置printf%#d%#i

printf [ -v varname ] format [ arg ... ]

...

  • ## 标志%d与不带输出基数的格式一起使用时,以 1000 的幂显示输出,由以下后缀之一指示:k M G T P E,与该格式一起使用时,%i以 1024 的幂显示输出,由以下后缀之一指示: Ki Mi Gi Ti Pi Ei

https://www.manpagez.com/man/1/ksh/

例如

$ K=1024  M=$((K * K))  G=$((M * K))  T=$((G * K))  P=$((T * K))  E=$((P * K))
$ KB=1000 MB=$((KB*KB)) GB=$((MB*KB)) TB=$((GB*KB)) PB=$((TB*KB)) EB=$((PB*KB))

$ printf "%#i\n" $((12e+12 + 1.2e+9 + 12e+6))
11Ti
$ printf "%#d\n" $(((58*$K + 2*$M)/2))
1.1M
$ printf "%#d\n" $((5 * (100*$G + 80*$M) + 2 * (300*$G + 15*$G + 800*$M)))
1.2T
$ printf "%#d\n" $((1.7*$GB + 320*$MB + 86*$KB))
2.0G

相关内容