LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   user group shell script (https://www.linuxquestions.org/questions/programming-9/user-group-shell-script-743744/)

mjhermanso21 07-29-2009 02:07 PM

user group shell script
 
I need a shell script that will print all users that belong to over 10 groups.

Currently I am getting the usernames from getent passwd, using awk get get the usernames, then running groups on each of the usernames. I have not figured out how I will count the groups yet but here is what I have so far.

Code:

#!/bin/sh

getent passwd > passwd.out

awk -F":" '{ print $1 }' ./passwd.out > users.out

cat users.out |while read line; do groups "${line}"; done

exit

This prints all the users and their groups, just very slowly. Also if I could do it without sending it to a file it should speed up.

Thanks

bigearsbilly 07-29-2009 02:29 PM

no file and a trick with IFS and read
any better?

Code:


(
IFS=:
getent passwd  |
while read u rest
do
  echo -n $u:
  id -Gn $u
done
)


catkin 07-29-2009 02:35 PM

Hello mjhermanso21 :)

Code:

for user in $( awk -F":" '{ print $1 }' < /etc/passwd )
do
        [[ $( groups $user | wc -w ) -gt 9 ]] && echo $user
done

Best

Charles

catkin 07-29-2009 02:43 PM

Inspired by bigearsbilly's techniques ...
Code:

IFS=':'
while read user rest
do
        [[ $(id -Gn $user | wc -w) -gt 10 ]] && echo $user
done < /etc/passwd

Edit: that leaves IFS set to : which doesn't matter if it's the end of the script. If it does matter you can get around it either by bigearsbilly's technique of running it in a subshell with (<stuff>) or by unsetting IFS afterwards:
Code:

IFS=':'
while read user rest
do
        [[ $(id -Gn $user | wc -w) -gt 10 ]] && echo $user
done < /etc/passwd
unset IFS


mjhermanso21 07-29-2009 03:38 PM

Thanks both of you. My only edit, which I didn't mention in my original post, was i wanted it to print like "user: groups...." so my final script was

#!/bin/sh

for user in $( awk -F":" '{ print $1 }' < ./passwd.out )
do
[[ $( groups $user | wc -w ) -gt 9 ]] && groups $user
done

*also we used LDAP not /etc/passwd so I am using a tmp file that has passwd info in it.

catkin 07-30-2009 03:09 AM

Quote:

Originally Posted by mjhermanso21 (Post 3624689)
Thanks both of you. My only edit, which I didn't mention in my original post, was i wanted it to print like "user: groups...." so my final script was

#!/bin/sh

for user in $( awk -F":" '{ print $1 }' < ./passwd.out )
do
[[ $( groups $user | wc -w ) -gt 9 ]] && groups $user
done

*also we used LDAP not /etc/passwd so I am using a tmp file that has passwd info in it.

That's mostly my version 0.1, before I smartened it up using bigearsbilly's ideas. More elegant would be
Code:

<command to write LDAP stuff to stdout> | while IFS=':' read user rest
do
        array=($(id -Gn $user))
        [[ ${#array[*]} -gt 10 ]] && echo ${array[*]}
done

As I learned in this LQ post a few days ago (thanks ntubski :)), that idiom leaves the original IFS untouched saving the need for a subshell or for saving+restoring/unsetting IFS.

mjhermanso21 07-30-2009 10:34 AM

very nice. and more efficient too!

catkin 08-02-2009 07:22 AM

Quote:

Originally Posted by mjhermanso21 (Post 3625598)
very nice. and more efficient too!

If the problem is solved, please use Thread Tools to mark it so.


All times are GMT -5. The time now is 01:08 PM.