Retrieve RAM memory size from "top" command output

Hi,

I am trying to get the system RAM size from "top" command's output by the following but it is not working.

top | sed "s/^Mem.*[^0-9]*\([0-9]*\), *//"

Post the output of your top command and the desired output.

# top | awk '/^Mem/ {print $2}'
32G

(If Solaris. But why use top?)

Linux.

$ top -n1 | awk '/^Mem/ {print $3}'
1026880k

The output is as follows:

top - 09:45:10 up 15:48,  1 user,  load average: 0.07, 0.02, 0.00
Tasks: 112 total,   1 running, 111 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   1025740k total,  1012624k used,    13116k free,   428188k buffers
Swap:  3004112k total,    74580k used,  2929532k free,   134616k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
    1 root      20   0  2848 1688  544 S    0  0.2   0:02.12 init
    2 root      15  -5     0    0    0 S    0  0.0   0:00.00 kthreadd

Thanks Scottn, but is it possible to do it via 'sed'??

Right tool for the right job and all that. You want to match a line and extract the third token? Well awk matches lines, and extracts tokens. You'd need to write a big monster of an expression to tell sed what you mean by 'token'.

But we can map any sequence of characters with '.*' right in Sed? Where I am going wrong in my code?

Are you looking for an output like this.. Mem: 1025740k from the top command..?

top | sed -n '/Mem/s/ [a-z]\+.*//p'

Hi.

As noted, it is a lot more work to extract a field with sed compared to awk. Here's one solution:

#!/usr/bin/env bash

# @(#) s1	Demonstrate complexity of sed compared to awk.

# Utility functions: print-as-echo, print-line-with-visual-space.
pe() { for i;do printf "%s" "$i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }

FILE=${1-data1}

pl " Input file $FILE:"
cat $FILE

pl " Results, sed:"
sed -n '/^Mem:/s/^[^0-9]*\([0-9]*.\).*$/\1/p' $FILE

exit 0

producing:

% ./s1

-----
 Input file data1:
top - 09:45:10 up 15:48,  1 user,  load average: 0.07, 0.02, 0.00
Tasks: 112 total,   1 running, 111 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   1025740k total,  1012624k used,    13116k free,   428188k buffers
Swap:  3004112k total,    74580k used,  2929532k free,   134616k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
    1 root      20   0  2848 1688  544 S    0  0.2   0:02.12 init
    2 root      15  -5     0    0    0 S    0  0.0   0:00.00 kthreadd

-----
 Results, sed:
1025740k

If you don't want the "k", omit the "dot" in the expression.

Best wishes ... drl

( Edit 1: minor typo )

Thanks michaelrozar17, but your solution is not giving me any output in my Ubuntu 8.04 Desktop edition 32-bit x86 machine :frowning:

Also, drl, your code:

top |  sed -n '/^Mem:/s/^[^0-9]*\([0-9]*.\).*$/\1/p'

gives output as 39; in my system.. why?

The given sed works if the top commands output looks exactly as in post# 4. However i have tried in my machine with the top | sed .. it works!. Else try with awk.

top | awk '/Mem/{print "Mem: " $2}'

Also remember there is a single space in between s/ and [a-z] in the sed command without which you would not get the expected output.

Oh, now I got to know that why I was not getting any output for your solution and output 39; for drl. By default the "top" command outputs the result with escape sequences which is not readable and cannot be processed normally by any filter commands. So, the output has to be changed to batch mode using "-b" option before feeding into 'sed'

Below command works perfectly:

top -b -n1 | sed -n '/Mem/s/ [a-z]\+.*//p'

Thanks a lot for all your replies :slight_smile: