Nested for loops

Greetings All,

The following script attempts to enumerate all users in all groups in the group file(GROUP) and echo the following information:

GROUP ---> USER

The script is as follows:

IFS=","
for GROUP in `ypcat -k group | cut -d" " -f1`
    do
        for USER in `ypcat -k group | grep $GROUP | cut -d":" -f4`
             do
                   echo "$GROUP -------> $USER"
             done
    done 

The unexpected result is that the group name is only printed. It appears that the outer loop variable loses scope inside of the inner loop.

Any ideas on why this occurs is greatly appreciated.

Pardon me, I don't understand the question. The outer loop variable is $GROUP and you say that groupname gets printed, so how does " outer loop variable loses scope inside of the inner loop ". If it was losing scope, only $USER Will get printed.

My apologies for the lack of clarity. I was thinking it was an issue with the $GROUP variable within the inner loop "for statement"(grep $GROUP):

for USER in `ypcat -k group | grep $GROUP | cut -d":" -f4`

I am new to bash scripting so I may be way off. When I run this the only output is the list of groups in the group file.

Are you sure you want to set IFS to comma, since it affects the way the for loops are being evaluated: they will now iterate over elements separated by commas.

Jack, try this, just one line, no for loops.

ypcat -k group|awk  -F:  '{for(i=4;i<=NF;i++) print $1 "--->" $i}'

Scrutinizer,

I was hoping that this would be useful in the comma delimited list of users resulting from the `ypcat -k group | grep $GROUP | cut -d":" -f4` output. Is there better way in bash to split a comma-delimited string of unknown length and loop through the results?

I am completely open to other easier methods of accomplishing this task.:slight_smile:

---------- Post updated at 08:38 PM ---------- Previous update was at 08:13 PM ----------

@dude --- I want to provide more information on exactly what I am trying to accomplish. We are migrating to Centrify from a NIS environment. I want to be able to loop through all groups in the group file, extract each member and bounce it off of the AD groups to ensure that they are in sync.

So here is what I have so far:

IFS=","
for GROUP in `ypcat -k group | cut -d" " -f1`
        do
        for USER in `ypcat -k group | grep $GROUP | cut -d":" -f4`
            do
                if (adquery group -a $GROUP | grep $USER) then
                    echo "$USER is in $GROUP"
                else
                    echo "$USER not found"
                fi 
                       done
        done 

Your suggestion looks pretty slick. Can I somehow modify it to accomplish the task at hand? Sorry I should have provided the background information earlier but my attempt to simplify the question actually complicated it.

@dude2cool, I think you need an extra separator, no?

awk -F[:,] '{for(i=4;i<=NF;i++) if($i)print $1 "--->" $i}'

@jacksolm: in shell, you could try something like this:

oldIFS=$IFS
IFS=,
ypcat -k group | 
while IFS=: read group x x users
do
  for user in $users
  do
    echo "$group ---> $user"
  done
done
IFS=$oldIFS

@scrutinizer, I guess it depends on how he wants it displayed. Without the comma separator, the output is:

tesgroup ---> test1, test2, test3

With the comma output is:
testgroup ---> test1
testgroup ---> test2
...and so on.
I personally like the first output with groupname followed comma separated values of users :), but ..

@dude2cool: I see, but then

ypcat -k group|awk -F: '{print $1 "--->" $4}'

Would suffice, no? (provided you want to print empty groups as well)

So do you think the following would work?

oldIFS=$IFS
IFS=,
ypcat -k group | while IFS=: read group x x users
do
  for user in $users
  do
   if (adquery group -a $group | grep $user) then
       echo "$user is in $group"
   else
      echo "$user not found"
   fi  
  done
done
IFS=$oldIFS

True. Much simpler, don't know why I went for that for loop :slight_smile:

You need a semicolon before then.
Just give it a try or perhaps this will work too:

if adquery group -a $group 2>/dev/null | grep -q $user; then

I will give that a try and let you both know the outcome. Thanks in advance for your time and assistance. This is a great website. I was amazed at the speedy response.
Thanks again!

Scrutinizer,

That worked like a charm! I made a few slight modifications to format reading from the group file and all is well.

Thanks to both you and Dude2cool for your time.