ylangylang
ylangylang

Reputation: 3474

Print unique names of users logged on with finger

I'm trying to write a shell script that prints the full names of users logged on to a machine. The finger command gives me a list of users, but there are many duplicates. How can I loop through and print out only the unique ones?

Edit:

This is the format of what finger gives me:

xxxx      XX of group XXX  pts/59   1:00  Feb 13 16:38 
xxxx      XX of group XXX  pts/71   1:11  Feb 13 16:27 
xxxx      XX of group XXX  pts/105    1d  Feb 12 15:22 
xxxx      YY of group YYY  pts/102  2:19  Feb 13 14:13 
xxxx      ZZ of group ZZZ  pts/42     2d  Feb  7 12:11 

I'm trying to extract the full name (i.e. whatever comes before 'of group' in column 2), so I would be using awk together with finger.

Upvotes: 2

Views: 1757

Answers (4)

xb.
xb.

Reputation: 1677

Could this be simpler? No spaces or any other special characters to worry about!

finger -l | awk '/^Login/'

Edit: To remove the content after of group

finger -l | awk '/^Login/' | sed 's/of group.*//g'

Output:

Login: xx                          Name: XX
Login: yy                          Name: YY
Login: zz                          Name: ZZ

Upvotes: 1

Martin Tournoij
Martin Tournoij

Reputation: 27822

What you want is actually fairly difficult in a shell script, here is, for example, my full output of finger(1):

Login             Name             TTY      Idle  Login  Time   Office  Phone
martin            Martin Tournoij *v0         1d  Wed    14:11
martin            Martin Tournoij  pts/2      22  Wed    15:37
martin            Martin Tournoij  pts/5      41  Thu    23:16
martin            Martin Tournoij  pts/7      31  Thu    23:24
martin            Martin Tournoij  pts/8          Thu    23:29

You want the full name, but this may contain 1 space (as per my example), or it may just be 'Teller' (no space), or it may be 'Captain James T. Kirk' (3 spaces). So you can't just use the space as delimiter. You could use the character position of 'TTY' in the header as an indicator, but that's not very elegant IMHO (especially with shell scripting).

My solution is therefore slightly different, we get only the username from finger(1), then we get the full name from /etc/passwd

#!/bin/sh

prev=""
for u in $(finger | tail +2 | cut -w -f1 | sort); do
        [ "$u" = "$prev" ] && continue
        echo "$u $(grep "^$u" /etc/passwd | cut -d: -f5)"
        prev="$u"
done

Which gives me both the username & login name:

martin Martin Tournoij

Obviously, you can also print just the real name (without the $u).

Upvotes: 3

rendon
rendon

Reputation: 2363

Other possible solution:

finger | tail -n +2 | awk '{ print $1 }' | sort | uniq
  • tail -n +2 to omit the first line.
  • awk '{ print $1 }' to extract the first column.
  • sort to prepare input for uniq.
  • uniq remove duplicates.

If you want to iterate use:

for user in $(finger | tail -n +2 | awk '{ print $1 }' | sort | uniq)
do
    echo "$user"
done

Upvotes: 1

Cloud
Cloud

Reputation: 19333

The sort and uniq BinUtils commands can be used to removed duplicates.

finger | sort -u

This will remove all duplicate lines, but you will still see similar lines due to how verbose the finger command is. If you just want a list of usernames, you can filter it out further to be very specific.

finger | cut -d ' ' -f1 | sort -u

Now, you can take this one step further, and remove the "header/label" line printed out by the finger command.

finger | cut -d ' ' -f1 | sort -u | grep -iv login

Hope this helps.

Upvotes: 1

Related Questions