1

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?

3 Answers 3

1

Parsing 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.


Reading /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
0

As alternative

cat /proc/meminfo | grep "MemFree\|SwapFree"
0

Another alternative:

free -h | awk '{print NR==1?$3:$1$4}'

will give you:

free  
Mem:30G  
Swap:14G  

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .