Listing out groups of users
You can get a list of all your local users with this command:
$ getent passwd | awk -F: '{print $1}'
NOTE: getent will return local users assuming you do not have sssd (or some similar service running which pulls LDAP users in too) and your /etc/nsswitch.conf is restricted to files, i.e. it's not including things like NIS or NIS+. For pure local user's only you can resort to awk -F: '{print $1}' /etc/passwd.
A list of who's currently logged in:
$ who
A list of user's that are currently not loggd in:
$ grep -Fxvf <(who | awk '{print $1}' | sort -u) \
<(getent passwd | awk -F: '{print $1}')
This last one takes the list of users who are logged in and shows the list of all user's minus the logged in users, using grep -vf.
Getting counts
To get counts, simply take a wc -l on to the end of commands.
not logged in
$ grep -Fxvf <(who | awk '{print $1}' | sort -u) \
<(getent passwd | awk -F: '{print $1}') | wc -l
53
logged in
$ who | awk '{print $1}' | sort -u | wc -l
1
grep flags
-F, --fixed-strings
Interpret PATTERN as a list of fixed strings, separated by newlines,
any of which is to be matched.
-x, --line-regexp
Select only those matches that exactly match the whole line.
-v, --invert-match
Invert the sense of matching, to select non-matching lines.
-f FILE, --file=FILE
Obtain patterns from FILE, one per line. The empty file contains
zero patterns, and therefore matches nothing.
Using join instead of grep
You could also forgo using grep and use join instead, since this type of problem is more in join's wheelhouse. We'll need to use join -v 2 which means that we want to exclude matches and only show the uniques from our second argument, getent ....
join man page
-a FILENUM
also print unpairable lines from file FILENUM, where FILENUM is
1 or 2, corresponding to FILE1 or FILE2
-v FILENUM
like -a FILENUM, but suppress joined output lines
$ join -v 2 <(who | awk '{print $1}' | sort -u) \
<(getent passwd | awk -F: '{print $1}' | sort) | wc -l
53
NOTE: The only caveat with using join is that both lists need to be sorted, so we have to add on a | sort to getent ....