#!/bin/bash
while IFS=: read username fullname usergroups
do
useradd -G $usergroups -c "$fullname" $username
done < users.txt
fullname is the only string that should contains whitespace (hence the quotes), A list of usergroups should be separated from the next by a comma, with no intervening whitespace (so no quotes on that argument) and your username should not contain whitespace either.
Upate:
To get the list of usergroups to create first you can do this...
#!/bin/bash
while IFS=: read username fullname usergroups
do
echo $usergroups >> allgrouplist.txt
done < users.txt
while IFS=, read group
do
echo $group >> groups.txt
done < allgrouplist.txt
sort -u groups.txt | while read group
do
groupadd $group
done
This is a bit long winded, and could be compacted to avoid the use of the additional files allgrouplist.txt and groups.txt but I wanted to make this easy to read. For reference here's a more compact version.
sort -u < $(
echo $(while IFS=: read a b groups; do echo $groups; done < users.txt )
| while IFS=, read group; do echo $group; done )
| while read group
do
groupadd $group
done
(I screwed the compact version up a bit at first, it should be fine now, but please note I haven't tested this!)
$(line)is really wrong, it will considerlineas a command, what you want is rather"$line"or"${line}".