I am using this command
free --mega
to show free memory and free swap. It shows total
, used
, free
, shared
, buff/cache
and available
. How do I get it to just show free memory for both only?
free
How do I get it to just show free memory for both only?
There is no option that does it. You need to parse the output.
free
is not specified by POSIX. By your description I assume free --mega
gives you something like this:
total used free shared buff/cache available
Mem: 4126 1624 116 5 2386 2227
Swap: 2146 1554 592
But it's different in this question from 2013:
total used free shared buffers cached Mem: 2496 2260 236 0 5 438 -/+ buffers/cache: 1816 680 Swap: 1949 68 1881
I don't know how many implementations of free
exist. In general different implementations may use different formats. The question is tagged ubuntu
, this narrows it to a certain implementation. Still the format may change in the future. For this reason parsing the output of free
is not totally reliable.
To get only the two numbers under free
, pick the 4th column from all lines but the first:
free --mega | awk 'NR!=1 {print $4}'
Maybe you want to keep the header. The string free
in the first line is visually in the 4th column, but formally (in the understanding of awk
) it's in the 3rd. Use this:
free --mega | awk '{print NR==1?$3:$4}'
And maybe you want to keep the first column:
free --mega | awk '
NR==1 {$0="dUm "$0}
{print $1" "$4}
' | column -t | sed 's/^dUm/ /'
Here dUm
is a dummy string designed to shift the first row, so free
ends up in the formal 4th column. Above we used awk
without this trick, but now column -t
requires it.
The following code uses few more tricks and allows you to pick or rearrange columns, or even calculate custom ones, all this by referring to their names:
LC_ALL=C free --mega | awk '
NR==1 {
$0="dUm"$0
for (i=1; i<=NF; i++) { lbl=$i; sub(" *$", "", lbl); ix[lbl]=i}
}
{ $0=$0" dUm dUm dUm"
print "x "$1" "$ix["free"]" "(NR==1?"%free":int(100*$ix["free"]/$ix["total"])"%")" "$ix["available"]" "$ix["total"]
}' | rev | column -t | rev | sed -e 's/dUm/ /g' -e 's/^x //'
LC_ALL=C
is in case free
is localized.
/proc/meminfo
Alternatively you can read values from /proc/meminfo
. Its format is somewhat easier to parse and it should be stable (i.e. it should not change in the future). Example:
</proc/meminfo grep -E '^(Mem|Swap)Free:'
The output will be like:
MemFree: 118380 kB
SwapFree: 531196 kB
It says kB
and some documentation says the values are "in kilobytes", but actually these are kibibytes. This ambiguity is not going to be fixed.
If you want megabytes (free --mega
in your question uses megabytes) then you should recalculate accordingly:
</proc/meminfo awk '$1~"^(Mem|Swap)Free:" {$2=$2*1024/1000000; $3="MB"; print}' | column -t
or maybe just:
</proc/meminfo awk '$1~"^(Mem|Swap)Free:" {$2=int($2*1024/1000000); $3=""; print}' | column -t
Another alternative:
free -h | awk '{print NR==1?$3:$1$4}'
will give you:
free
Mem:30G
Swap:14G