2

I am trying to parse the output of my top results to pickout the timestamp, used Mem and used Swap:

top - 12:06:52 up  3:36, 37 users,  load average: 0.00, 0.02, 0.00
Tasks: 563 total,   1 running, 562 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.3%us,  0.1%sy,  0.0%ni, 99.6%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  65968400k total,  9594508k used, 56373892k free,   199136k buffers
Swap: 68026360k total,        0k used, 68026360k free,  5864056k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                    
11527 root      15   0 26464 1728 1056 R  1.9  0.0   0:00.01 top                                                        

So that's a sample of it. Now I got the awk cmd below:

awk '$1 ~/top/ {print $5;} $1 ~/Mem/ {print $4;} $1 ~/Swap/  {print $4;}' top-output

But it is not perfect because it outputs everything in a new line. Like this:

7:40,
12644016k
0k
7:50,
12411248k
0k 
8:04,
12795392k
0k

I want it to output like this instead:

7:40, 12644016k, 0k
7:50, 12411248k, 0k

How do I do that? Thanks

1

1 Answer 1

2

One method is to use printf:

$ awk '$1 ~/top/ {printf "%s ",$5;} $1 ~/Mem/ {printf "%s ",$4;} $1 ~/Swap/  {print $4;}' top-output
3:36, 9594508k 0k

printf offers flexible formatting and it does not, unless you explicitly tell it to, print a newline character. The first argument to printf is the format string for printf. The format string is documented in man awk.

Another method to save the values and use print just once:

$ awk '$1 ~/top/ {up=$5;} $1 ~/Mem/ {used=$4;} $1 ~/Swap/  {print up,used,$4;}' top-output
3:36, 9594508k 0k

Adding the extra comma

$ awk '$1 ~/top/ {printf "%s ",$5;} $1 ~/Mem/ {printf "%s, ",$4;} $1 ~/Swap/  {print $4;}' top-output
3:36, 9594508k, 0k

$ awk '$1 ~/top/ {up=$5;} $1 ~/Mem/ {used=$4;} $1 ~/Swap/  {print up,used",",$4;}' top-output
3:36, 9594508k, 0k

Stripping out the k

With printf, we can specify an integer format and that forces conversion to a number which removes the k:

$ awk '$1 ~/top/ {printf "%s ",$5;} $1 ~/Mem/ {printf "%i, ",$4;} $1 ~/Swap/  {print $4;}' top-output
3:36, 9594508, 0k

Another way to force a conversion to a number is to add zero to it. Thus, the following uses used=$4+0 in place of used=$4:

$ awk '$1 ~/top/ {up=$5;} $1 ~/Mem/ {used=$4+0;} $1 ~/Swap/  {print up,used",",$4;}' top-output
3:36, 9594508, 0k

Removing the comma from the uptime

The uptime has a colon between two numbers and awk cannot convert it to a number. That means that other approaches are needed. One way to make the comma disappear from the output is adding a comma to the field separator:

$ awk -F'[,[:space:]]+' '$1 ~/top/ {printf "%s ",$5;} $1 ~/Mem/ {printf "%s ",$4;} $1 ~/Swap/  {print $4;}' top-output
3:36 9594508k 0k

$ awk -F'[,[:space:]]+' '$1 ~/top/ {up=$5;} $1 ~/Mem/ {used=$4+0;} $1 ~/Swap/  {print up,used,$4;}' top-output
3:36 9594508 0k
6
  • sweet thanks! Just a quick followup how do I strip out the k?
    – D.Zou
    Commented Aug 7, 2015 at 19:54
  • @D.Zou Your welcome. The answer is updated with versions that remove the k.
    – John1024
    Commented Aug 7, 2015 at 19:58
  • why does adding a zero force it to drop the k?
    – D.Zou
    Commented Aug 7, 2015 at 20:06
  • In awk, variables can be treated as either string or number, depending on context. Addition forces a numeric context. This is true even for simple operations like adding zero. The numeric context means that awk has to convert the string 9594508k to a number which, in this case, is 9594508.
    – John1024
    Commented Aug 7, 2015 at 20:09
  • sorry for another question, what if I want to strip out the comma after the timestamp? I tried it to add the zero and %i but neither results were correct.
    – D.Zou
    Commented Aug 7, 2015 at 20:39

You must log in to answer this question.

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