All groups are in the group database. To count the number of members of a group, extract the members and count the commas in-between them. The number of group members is 1 plus this number.
#!/bin/sh
n=$( getent group "$1" | cut -d : -f 4 | grep -o , | wc -l )
printf 'There are %d members of group %s\n' "$(( n + 1 ))" "$1"
The downside of this approach is that you will always get at least 1 member as output, even if the group is invalid. We can test for a valid group first though:
#!/bin/sh
if ! getent group "$1" >/dev/null; then
printf 'No such group: %s\n' "$1" >&2
exit 1
fi
n=$( getent group "$1" | cut -d : -f 4 | grep -o , | wc -l )
printf 'There are %d members of group %s\n' "$(( n + 1 ))" "$1"
The script accept both numeric GIDs and group names as its first command line argument.
With awk, you would instead do
n=$( getent group "$1" | awk -F : '{ print split($4,dummy,",") }' )
and then not add 1 to $n later, or just
getent group "$1" | awk -F : '
{
printf("There are %d members of group %s (%d)\n",
split($4,dummy,","), $1, $3)
}'
without the (shell) printf or the n variable.
This counts group memberships as recorded in the group database. To count only primary group memberships, use something like
n=$( getent passwd | cut -d : -f 4 | grep -cxF "$1" )
But again, you may want to check that $1 is indeed a valid group ID first.
To count both primary and supplementary group memberships, it may be best to loop over all users and use id on each:
getent passwd | cut -d : -f 1 |
while read user; do
if id -G "$user" | tr ' ' '\n' | grep -q -xF "$1"; then
n=$(( n + 1 ))
fi
done
This would extract all usernames, then call id -G on each and transform the resulting list of GIDs into a newline-delimited list. The grep then determines whether the given GID is part of that list, and if it is, n is incremented by one.
Or quicker, but uglier,
n=$( getent passwd | cut -d : -f 1 |
while read user; do
id -G "$user"
done | tr ' ' '\n' | grep -c -xF "$1" )
or even,
n=$( getent passwd | cut -d : -f 1 |
xargs -n 1 id -G | tr ' ' '\n' |
grep -c -xF "$1" )
The reason this may be a good approach is that there may be users whose primary group does not contain themselves in the group database.