With GNU sed
you can do domething like
sed -zE 's_.*MemTotal: *([0-9]*).*\nMemFree: *([0-9]*).*\nBuffers: *([0-9]*).*\nCached: *([0-9]*).*_echo $(((\1-\2-\3-\4)/1024)) MB_e' /proc/meminfo
The -z
option reads the whole file proc/meminfo
in a single buffer to extract all four values in a single regular expression and form the calculation out of it to use the dangerous e
flag of the s
command to execute the command.
For POSIX sed
versions without -z
and without e
flag, you can fill the sed
extraction in your calculation by command substitution (equally dangerous):
echo $(( ($(sed -E '/^(MemTotal|MemFree|Cached|Buffers): *([0-9]*).*/{s//\2/;H;};$!d;x;s/[[:cntrl:]]//;s//-/g' /proc/meminfo)) / 1024)) MB
I know the lines are long, but both are one-liners somehow.
Update: Different rounding
In the comment there was a request to first convert each value to MB prior to substraction. Here is the modified script:
echo $(( $(sed -E '/^(MemTotal|MemFree|Cached|Buffers): *([0-9]*).*/{s//\2/;H;};$!d;x;s/[[:cntrl:]]//;s__/1024-_g;s_$_/1024_' /proc/meminfo))) MB
Please note that this results in additional rounding errors. For example
MemTotal: 16359572 kB
MemFree: 6614000 kB
Buffers: 602108 kB
Cached: 3685372 kB
will output 5333 MB instead of 5330 MB (true value: 5330.16 MB).