How can I find the value before the word "free"?

top -n1 | grep Mem                   
Mem:  2054968k av, 2034120k used,   20848k free,       0k shrd,  186768k buff

First I tried

  top -n1 | grep Mem  | awk '{print $7}'

but this isn’t good because the free value (here, 20848k) can be in different fields. Sometimes it's field 6, others field 7 and so on.

I need this to work on both Linux and Solaris.

awk -v RS="[, ]" '/free/{print a}{a=$0}'


  • Set the record separator to , and space, so the number preceding every string is a record in itself, and so is the string.
  • Having everything as its own record, awk will process every item one by one
  • For all the records before free it will ignore the {print a} because the condition doesn't match, and it will skip to {a=$0} which will store the currently processed record in variable a
  • Once /free/ is matched, awk will just {print a} where a contains the record right before the match
  • Hi this should work on linux and on solaris , is this code support the both OS? – maihabunash Oct 1 '14 at 15:59
  • I only tested it with GNU Awk 4.1.1 – confused00 Oct 1 '14 at 16:03
$ top -bn1 | grep free
KiB Mem:   8117084 total,  6578888 used,  1538196 free,   302216 buffers
KiB Swap:  8060924 total,    26004 used,  8034920 free,  1564856 cached
$ top -bn1 | grep -oP '\S+(?=\s+free)'

requires GNU grep, but you've tagged "linux", so you're OK

For just the "Mem":

top -bn1 | grep -oP 'Mem.*\s\K\S+(?=\s+free)'
  • Hi this should work on linux and on solaris , is this code support the both OS? – maihabunash Oct 1 '14 at 15:58
  • top -bn1 | grep -oP 'Mem.*\s\K\S+(?=\s+free)' ( not work on my linux machine ) I tested it again no any output – maihabunash Oct 1 '14 at 16:01

Using GNU sed (Linux only):

top -bn1 | sed -rn '/Mem/{s/.* ([^ ]*) free.*/\1/p;}'

Using any sed:

top -bn1 | sed -n '/Mem/{s/.* \([^ ]*\) free.*/\1/p;}'

Using perl:

top -bn1 | perl -lne '/Mem.* ([\d]+)\s*free/ && print $1'

Using a tool designed for the job (tested on Linux, not sure if free is available on Solaris):

free | awk '/Mem/{print $4}'

Another tool designed for the job (should work on both Linux and Solaris):

vmstat 2 2 | tail -n 1 | awk '{print $4}'

Going to the source (this works on Linux, not sure about Solaris):

awk '/MemFree/{print $2}' /proc/meminfo 
  • about using any sed ( I found problem when - Memory: 7168M phys mem, 2404M free mem, 10G total swap, 10G free swap ) you take the second free , while we need the first one – maihabunash Oct 1 '14 at 16:08
  • @maihabunash I added some other approaches. However, next time, please show us both outputs you need to parse. We don't know what your system will print. – terdon Oct 1 '14 at 16:12
  • OK , can you update the top -bn1 | sed -n '/Mem/{s/.* ([^ ]*) free.*/\1/p;}' , so it will take the first free value ? – maihabunash Oct 1 '14 at 16:15
  • @maihabunash I could but only if you show me the output you need to parse. Otherwise, I'd just be guessing. – terdon Oct 1 '14 at 16:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.