目标
在Linux上,我正在尝试获取一个用户友好的字符串来表示可用系统内存。
例如:
Your computer has 4 GB of memory.
成功标准
我认为以下方面更加易于最终用户理解(您可能不同意):
1G
比1.0G
更易读(1
vs1.0
)1GB
比1G
更易读(GB
vsG
)1 GB
比1GB
更易读(以空格分隔的
计量单位)memory
比RAM
、DDR
或DDR3
更易读(无行话)
起点
free 实用程序来自 procps-ng,其中有一个选项是为人类设计的:
-h, --human
Show all output fields automatically scaled to shortest three digit unit
and display the units of print out. Following units are used.
B = bytes
K = kilos
M = megas
G = gigas
T = teras
If unit is missing, and you have petabyte of RAM or swap, the number is
in terabytes and columns might not be aligned with header.
所以我决定从那里开始:
> free -h
total used free shared buffers cached
Mem: 3.8G 1.4G 2.4G 0B 159M 841M
-/+ buffers/cache: 472M 3.4G
Swap: 4.9G 0B 3.9G
3.8G
听起来很有前途,现在我所要做的就是...
必要步骤
过滤输出以获取包含人类可读字符串(即
Mem:
)的行从该行中间提取出内存总量(即
3.8G
)解析数字和度量单位(即
3.8
和G
)格式化并显示我更喜欢的字符串(例如
G
↝GB
,...)
我的尝试
free -h | \
awk '/^Mem:/{print $2}' | \
perl -ne '/(\d+(?:\.\d+)?)(B|K|M|G|T)/ && printf "%g %sB\n", $1, $2'
输出:
3.8 GB
所需解决方案
我更倾向于仅使用gawk,但我不知道如何操作
使用更好的方法,即使有标准的方法从字符串中解析出“浮点数”
我不介意一丝不苟地匹配“只有被识别为幅度字母”的字母
(B|K|M|G|T)
,即使这会不必要地破坏与新尺寸的引入的匹配我使用
%g
将4.0
输出为4
,这是你可能会反对的,具体取决于你对这些评论的感觉:https://unix.stackexchange.com/a/70553/10283。
我的问题总结
- 你能只用
awk
来完成上面的任务吗? - 保持代码严谨性,是否有更优雅的方式编写我的
perl
代码?
记住:
I am a beginner robot. Here to learn. :]
我从安迪·莱斯特那里学到了什么
在此总结出来,以加深我的学习。
例如,这个gawk:
echo foo bar baz | awk '{print $2}'
可以这样用Perl编写:
echo foo bar baz | perl -ane 'print "$F[1]\n";'
除非有类似于 gawk 的--field-separator
,否则我认为我还是更喜欢 gawk ,尽管当然在 perl 中完成所有操作既更清洁又更高效。(是否有相应的功能?)
编辑:实际上,这证明了有一个选项-F
,就像在gawk中一样:
echo ooxoooxoooo | perl -Fx -ane 'print join "\n", @F'
输出:
oo
ooo
oooo
- Perl有一个
-l
选项,非常棒:可以将其视为Python的str.rstrip(如果您不是Python专家,请查看链接以了解$_
的有效性),但它会自动重新添加\n
到输出中。
谢谢,Andy!