Dan Dan - 7 months ago 16
Bash Question

Using egrep within loop

I'm trying to loop through a list of usernames and print out groups they belong to, but omitting ones I'm not interested in. But it's not working. And no, I'm no shell script expert.

#!/bin/bash
PATH=/bin:/usr/bin:/sbin:/usr/sbin export PATH

# This script runs through list of user IDs
# and spits out the groups they belong to

while IFS= read -r line
do
GROUPSS=$(groups $line)

RESULT=$(egrep -v "_unknown|sciences|everyone|netaccounts" $GROUPSS)
echo $line $GROUPSS
done < $1

Answer

Consider:

RESULT=$(egrep -v "_unknown|sciences|everyone|netaccounts" $GROUPSS)

After the regex, egrep expects to find filenames on its command line. The line above, however, provides it with a list of groups. Fortunately, egrep can also accept input from stdin. So, we can provide the list of groups there.

There is another catch, though. egrep operates on a line at a time but the information in the GROUPSS variable is space-separated not newline-separated. So, we need to change that.

Putting that all together:

while IFS= read -r line
do
    result=$(groups "$line" | sed 's/ /\n/g' | egrep -v "_unknown|sciences|everyone|netaccounts")
    echo $result
done < $1

On my system, groups returns the user name followed by a colon followed by the list of groups. The pipeline does not remove the user name or colon. Consequently, for output it is sufficient to use echo $result.

Variation

Some consider tr easier to use than sed. For them, this alternative may be preferred:

results=$(groups "$line" | tr ' ' '\n' | egrep -v "_unknown|sciences|everyone|netaccounts")