将打印的内存使用量从点更改为逗号,然后以 % 形式计算内存使用量

将打印的内存使用量从点更改为逗号,然后以 % 形式计算内存使用量

到目前为止,在之前提出的问题中:使用 /proc/meminfo 单行计算实际内存使用情况(memtotal - memfree - cached - bufferd)

非常感谢@Philippos,此命令可以打印正确的内存使用情况:

echo $(( $(sed -E '/^(MemTotal|MemFree|Cached|Buffers): *([0-9]*).*/{s//\2/;H;};$!d;x;s/[[:cntrl:]]//;s__/1024-_g;s_$_/1024_' /proc/meminfo))) > test && awk -v CONVFMT='%.2f' '{print $1/1024""}' test && rm test

这打印:

1.32

这非常接近我在 bash 中单行计算的最终值。但是,尝试添加更多步骤(例如令人尴尬地创建一个文件和多个相同的命令)并尝试将所有点转换为逗号。我无法将值打印为:

1,32

这个命令/解决方案适合我传递给朋友的东西,使其在 python 中显示在 OLED 屏幕上。

然而,下一步也是最后一步是计算与系统内存总量相比的使用率(以百分比为单位)。所以像这样:

43%

然后应该从给定的一句话中出来。

感谢大家花时间阅读和帮助,非常感谢!

答案1

您可以使用 printf(1) 实用程序进行输出。请man 3 printf参阅 参考资料 中格式说明符的描述。尤其,

对于某些数字转换,使用基数字符(“小数点”)或千位分组字符。实际使用的字符取决于语言环境的 LC_NUMERIC 部分。 (请参阅 setlocale(3)。)POSIX 语言环境使用“.”作为基数字符,并且没有分组字符。因此, printf("%'.2f", 1234567.89); 在 POSIX 语言环境中结果为“1234567.89”,在 nl_NL 语言环境中结果为“1234567,89”,在 da_DK 语言环境中结果为“1.234.567,89”。

printf "%0.2f MB\n" $(( $(sed -E '/^(MemTotal|MemFree|Cached|Buffers): *([0-9]*).*/'\
'{s//\2/;H;};$!d;x;s/[[:cntrl:]]//;s__/1024-_g;s_$_/1024_' /proc/meminfo) ))

至于百分比输出,除以 1024 只会导致精度损失,并且可能不是所希望的。因此:

printf "%d%%\n" $(( $(sed -E '/^(MemTotal|MemFree|Cached|Buffers): *([0-9]*).*/'\
'{s//\2/;H;};$!d;x;s/[[:cntrl:]]//;s_([^\n]+)\n_@\1@100*(\1-(_;s_\n_+_g;'\
's_@([^@]+)@(.*)$_\2))/\1_' /proc/meminfo) ))

请注意,上述命令中的正则表达式可能可以变得更加优雅/紧凑。

将两个命令合并为一个:

printf "%0.2f MB %d%%\n" $(( $(sed -E '/^(MemTotal|MemFree|Cached|Buffers): *([0-9]*).*/'\
'{s//\2/;H;};$!d;x;s/[[:cntrl:]]//;s__/1024-_g;s_$_/1024_' /proc/meminfo) )) \
$(( $(sed -E '/^(MemTotal|MemFree|Cached|Buffers): *([0-9]*).*/'\
'{s//\2/;H;};$!d;x;s/[[:cntrl:]]//;s_([^\n]+)\n_@\1@100*(\1-(_;s_\n_+_g;'\
's_@([^@]+)@(.*)$_\2))/\1_' /proc/meminfo) ))

更新:要使用以 MB 为单位的量计算已用内存的百分比,尽管精度损失,可以改为执行:

printf "%d%%\n" $(( $(sed -E '/^(MemTotal|MemFree|Cached|Buffers): *([0-9]*).*/'\
'{s//\2/;H;};$!d;x;s/[[:cntrl:]]//;s_([^\n]+)\n_@\1@100*(\1/1024-(_;s_\n_/1024+_g;'\
's_@([^@]+)@(.*)$_\2/1024))/(\1/1024)_' /proc/meminfo) ))

在必要的地方添加/1024。在这种情况下,具有两种计算的单个命令将变为:

printf "%0.2f MB %d%%\n" $(( $(sed -E '/^(MemTotal|MemFree|Cached|Buffers): *([0-9]*).*/'\
'{s//\2/;H;};$!d;x;s/[[:cntrl:]]//;s__/1024-_g;s_$_/1024_' /proc/meminfo) )) \
$(( $(sed -E '/^(MemTotal|MemFree|Cached|Buffers): *([0-9]*).*/'\
'{s//\2/;H;};$!d;x;s/[[:cntrl:]]//;s_([^\n]+)\n_@\1@100*(\1/1024-(_;s_\n_/1024+_g;'\
's_@([^@]+)@(.*)$_\2/1024))/(\1/1024)_' /proc/meminfo) ))

更新2:如果您在 Bash 中以交互方式输入上述命令,则由于 Bash 在交互模式下和处理脚本时的不同行为(关于\<newline>inside 内部的组合)$(),该命令可能无法工作$(())。其他 shell,例如 mksh(我正在使用)在这方面不会以不同方式处理交互式输入的命令。

以下是可读性较差的命令,如很长的行:

百分比:

printf "%d%%\n" $(( $(sed -E '/^(MemTotal|MemFree|Cached|Buffers): *([0-9]*).*/{s//\2/;H;};$!d;x;s/[[:cntrl:]]//;s_([^\n]+)\n_@\1@100*(\1/1024-(_;s_\n_/1024+_g;s_@([^@]+)@(.*)$_\2/1024))/(\1/1024)_' /proc/meminfo) ))

两个输出都在一个命令中:

printf "%0.2f MB %d%%\n" $(( $(sed -E '/^(MemTotal|MemFree|Cached|Buffers): *([0-9]*).*/{s//\2/;H;};$!d;x;s/[[:cntrl:]]//;s__/1024-_g;s_$_/1024_' /proc/meminfo) )) $(( $(sed -E '/^(MemTotal|MemFree|Cached|Buffers): *([0-9]*).*/{s//\2/;H;};$!d;x;s/[[:cntrl:]]//;s_([^\n]+)\n_@\1@100*(\1/1024-(_;s_\n_/1024+_g;s_@([^@]+)@(.*)$_\2/1024))/(\1/1024)_' /proc/meminfo) ))

相关内容