假设我有一堆代表内存量的数字,以86k
或320m
或的形式编写1.7g
。如何在命令行中计算它们的总和,并返回人类可读的结果?
能够计算减法也很好。完美的工具可以处理多组符号(例如1g
/ 1G
/ 1GB
/ 1Go
/ 1GiB
/ 1.7Gio
)及其含义(二进制或十进制乘数)。
我正在寻找一个纯粹的计算器。这些数字不一定是我磁盘上某些文件的大小,因此不能选择find
、stat
或等工具。du
这显然很容易实现(在精度方面存在一些障碍),但如果这还不存在,我会被诅咒的!
答案1
答案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)的结果。
它不理解86k
or320m
或1.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
。
例如
$ 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