tags:

views:

371

answers:

3

Hello everybody, I have to solve an exercise using awk. Basically I need to retrieve from 'ps aux' command the total of memory usage for each user and format like this:

User    Total%Mem
user1      3.4%
user2      1.5%

and so on.

The problem I can't seem to solve is: how do I know how many users are logged in? And how can I make a different sum for each one of them?

Thank you :)

A: 

You would use associative arrays to accumulate the memory usage per user. You don't need to know how many users there are because you can iterate over the array. Why don't you show what you have so far?

Here is the basic structure, in pseudocode, that a program like this would have:

BEGIN { print headers, do other setup if needed }

{ 
    add the %mem field to the array element indexed by the user name
}

END {
    for each element in the array
        print the name and the total
        add the total to a grand total
    print the grand total
}
Dennis Williamson
A: 
ps -eo user,pmem| awk 'NR>1{u[$1]+=$2}END{for(i in u)print "user: "i",mem: "u[i]}'
ghostdog74
A: 

You don't need to know any of that. All you need to know is:

  1. You have columnar output with the same number of columns in each row.
  2. The first column is the user login name.
  3. The 4th column is the %MEM column.
  4. Awk initializes variable at 0 automatically.
  5. Awk index keys are arbitrary values :)

    ps aux | awk 'NR != 1 {x[$1] += $4} END{ for(z in x) {print z, x[z]"%"}}'
    

I pipe the input to awk, and then I tell it to skip line 1 (NR != 1). Then for every single line, it reads in English like this:

in array 'x', increment the value in 'x[username]' by the value in the 4th column. If the array key doesn't exist yet, create it, initialized at 0, and then increment that by the value in the 4th column.

When Awk has done this for every single line, it runs the code in the 'END' block, which says to print out each user name (z in x), and the final aggregated value associated with that user (x[z]), followed by a "%".

If you want to see it build line by line, you can use the same basic rules, but add a print after each line is processed instead of in the 'END':

ps aux | awk 'NR != 1 {x[$1] += $4; print $1, x[$1]}'
jonesy
Thank you really much!I knew each element in your list, but I can't put them all together :D
JustB