How can I get the PID column from the output of `who -u`?

How can I get the PID column from the output of `who -u`?
typescript
Ethan Jackson

Background

Calling who -Hu on my machine gives this result:

$ who -Hu NAME LINE TIME IDLE PID COMMENT rpi-first-boot-wizard tty7 1970-01-10 11:44 02:31 1204 (:0) user-x tty2 1970-01-07 20:16 00:10 2670 user-x pts/0 4164607823021491175 . 2756 (192.168.203.57)

Problem

I am interested in the PID column for user-x. So what I want is 2670 and 2756.

What I tried

I looked through the man pages of who, but there are no options to get a specific column or to suppress certain columns.

I tried with who -u | grep user-x | tr -s ' ' | cut -d ' ' -f 5, but that only works for the row(s) that have the timestamp as a single number with no spaces. For some reason, some of the lines have a timestamp that includes spaces, so it's hard to parse.

What I want

It would be nice to have some simple bash command(s) that I could use to get the PIDs from the output. I'm just not sure exactly how to manipulate the strings correctly. I would rather not have to use a programming language to parse this output, but if I can't find out a nice way to do it with bash, then that's what I will have to end up doing.

Other info

In case this is an "XY problem," what I am really trying to do is kick a specific user out of my system, so I plan to pass these PIDs into kill, like who -u | grep user-x | tr -s ' ' | cut -d ' ' -f 5 | xargs kill. This worked like a charm until I started encountering sessions that use this wonky date format with the spaces. If there is another way to get the right PIDs that does not include using who, then that would also suffice.

Answer

Assuming you want to capture the PIDs for some other reason besides issuing a kill (eg, appending to a log file) ...

Using the following file to simulate OP's who -Hu call:

$ cat who.out NAME LINE TIME IDLE PID COMMENT rpi-first-boot-wizard tty7 1970-01-10 11:44 02:31 1204 (:0) user-x tty2 1970-01-07 20:16 00:10 2670 user-x pts/0 4164607823021491175 . 2756 (192.168.203.57)

One approach using awk:

cat who.out | awk -v user="user-x" ' $1==user { gsub(/\([^)]+\)/,"") # strip off the parenthesized string at end of line print $1, $NF # print 1st and last fields } ' ######## # or as a one-liner: cat who.out | awk -v user='user-x' '$1==user { gsub(/\([^)]+\)/,"") ; print $1, $NF}'

These both generate:

user-x 2670 user-x 2756

If you only need the PIDs in the output then change print $1, $NF to print $NF.

In OP's case the call would look like:

who -Hu | awk -v user='user-x' '$1==user { gsub(/\([^)]+\)/,"") ; print $1, $NF}'

Related Articles