8

I have command to list system process by memory usage:

ps -A --sort -rss -o comm,pmem

Which list a table like

COMMAND         %MEM
firefox         28.2
chrome           5.4
compiz           4.8
atom             2.5
chrome           2.3
Xorg             2.3
skype            2.2
chrome           2.0
chrome           1.9
atom             1.9
nautilus         1.8
hud-service      1.5
evince           1.3

I would like to get total memory share per programs instead of per process of same programs. So I could get output like

COMMAND         %MEM
firefox         28.2
chrome          11.6
compiz           4.8
atom             4.4
Xorg             2.3
skype            2.2
nautilus         1.8
hud-service      1.5
evince           1.3

I thought about using awk, which I don't know much. Ended up with something like:

ps -A --sort -rss -o comm,pmem | awk -F "\t" '
{processes[$0] += $1;}
{End
for(i in processes) {
  print i,"\t",processes[i];
}
}'

But it didn't work.

How can I correct this?

2 Answers 2

12

processes[$0] += $1; use the whole line as key in your associative array, which is not unique. You must use $1, which is command name as key.

Try:

$ ps -A --sort -rss -o comm,pmem | awk '
  NR == 1 { print; next }
  { a[$1] += $2 }
  END {
    for (i in a) {
      printf "%-15s\t%s\n", i, a[i];
    }
  }
'

If you want to sort the output by the second field, try:

$ ps -A --sort -rss -o comm,pmem | awk '
  NR == 1 { print; next }
  { a[$1] += $2 }
  END {
    for (i in a) {
      printf "%-15s\t%s\n", i, a[i] | "sort -rnk2";
    }
  }
'
5
  • Sorry, that if was typing mistake. I corrected it.
    – Junaid
    Nov 11, 2014 at 8:13
  • It seems to be working. Will it be possible to have sorted by second column (Memory) in ascending order?
    – Junaid
    Nov 11, 2014 at 8:15
  • Wondering how sort statement along with printf decide the sorting :) weird!
    – Junaid
    Nov 11, 2014 at 9:53
  • @cuonglm, How I can add one more column cpu in this command. Oct 4, 2018 at 15:37
  • FWIW, I couldn't figure out why this wasn't working for me (was producing a single line of incorrect output) and then I realized the original input had a line of column names and mine did not. I removed the NR == 1 line and it seemed to work. Jan 27, 2022 at 13:21
2

cuonglm answer solves your typo, to get the values in ascending order (as asked in your comment), pipe the output through sort -n -k 2 (sort as numbers (-n, on second field (-k 2), after changing the print statement to output the floats as in your example:

$ ps -A --sort -rss -o comm,pmem | awk '
  NR == 1 { print; next }
  { a[$1] += $2 }
  END {
    for (i in a) {
      printf "%-15s\t%.1f\n", i, a[i];
    }
  }
' | sed 's/%MEM/-1MEM/' | sort -n -k 2 | sed 's/-1MEM/%MEM/'

Output (using your table as input instead of doing ps on my system):

COMMAND         %MEM
evince          1.3
hud-service     1.5
nautilus        1.8
skype           2.2
Xorg            2.3
atom            4.4
compiz          4.8
chrome          11.6
firefox         28.2

Alternatively you can pipe the output through this python program (if you want descending sort (as in your example), change the reverse=False into reverse=True:

#! /usr/bin/env python
# coding: utf-8

import sys
import operator

d = {}
for line in sys.stdin:
    try:
        name, val = line.split()
        val = float(val)
        d.setdefault(name, [0.0])[0] += val
    except ValueError:
        print line,

for x in sorted(d.items(), reverse=False, key=operator.itemgetter(1)):
    print "{:16s}{:>4}".format(x[0], x[1][0])
6
  • This will break the header line.
    – cuonglm
    Nov 11, 2014 at 8:29
  • @cuonglm What do you mean by that? It stays on one line and is at the top.
    – Anthon
    Nov 11, 2014 at 8:35
  • Did you actually run ps -A --sort -rss -o comm,pmem in your machine? Something like acpid 0 compare with COMMAND %MEM can break the result
    – cuonglm
    Nov 11, 2014 at 8:37
  • @cuonglm I had not, I see the problem is you printed the float values as strings. Corrected, thanks.
    – Anthon
    Nov 11, 2014 at 8:59
  • @Anthon Header line get printed at wrong place.
    – Junaid
    Nov 11, 2014 at 9:55

You must log in to answer this question.

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