formatting script

Disclaimer: I did not set out to write the next big thing...

I'm simply collecting all of the group information for all of the users across disparate hosts.

I wrote a simple script to collect all of the group information for each user on a system and pushed it out to each host:

#!/bin/sh
for user in `awk -F: '{print $1}' /etc/passwd`; do echo "$user:"; groups $user; echo "#################"; done

I collected them on a central host

for host in `cat hosts`; do ssh $host /tmp/myScript.sh >> ../collected/$host; done

To clean it up and move each new group onto it's own line, I quickly ran it through tr

cd ../collected
for file in `ls`; do tr ' ' '\n' < $file >> ../uidgames/$file; done

But now, I'm left with a handful of files that look like this:

daemon:
other
bin
adm
daemon
#################
bin:
bin
sys
#################
sys:
sys
#################
adm:
adm
sys
tty
lp
#################
lp:
lp
#################

Ideally, I'd like the file to look like this:

daemon:other
daemon:bin
daemon:adm
daemon:daemon
bin:bin
bin:sys
sys:sys
adm:adm
adm:sys
adm:tty
adm:lp
lp:lp

And then I'll collect them all together with a simple:

for file in `ls`; do awk '{print FILENAME":"$0}' $file >> ../result; done

This is a file that I can drop into Excel to get moving on my UID/GID cleanup plan.

I've been playing with this for 30 minutes, but need to go home before I start seeing hash marks everywhere.

If you have a great idea to do this all from go to whoa, great, but all I'm really looking for is that one piece. I'll munge it all together later, just looking for "quick and dirty" right now...

Thanks!

  • Avron

Is this what you are looking for ?

for user in `awk -F: '{print $1}' /etc/passwd`; do groups $user|awk '{n=split($0,x); for (i=3; i<=n; ++i) {print x[1]":"x;}}'; done
$                                                                                                             
$ for user in `awk -F: '{print $1}' /etc/passwd`; do groups $user|awk '{n=split($0,x); for (i=3; i<=n; ++i) {print x[1]":"x;}}'; done
root:root
root:bin 
root:daemon
root:sys   
root:adm   
root:disk  
root:wheel 
bin:bin    
bin:daemon 
bin:sys    
daemon:daemon
daemon:bin   
daemon:adm   
daemon:lp    
adm:adm      
adm:sys      
lp:lp        
sync:root
shutdown:root
halt:root
mail:mail
uucp:uucp
operator:root
games:users
...
... (clipped output)

HTH,
tyler_durden

____________________________________________________
"Only after disaster can we be resurrected."

Looks great, thanks!

I like how you trimmed out two complete portions of my hackery with the 'awk split'. Back to the books for me, it seems...

Cheers,

  • Avron

For the record book...

The solaris output from the groups command is different from the linux output:

linux:

[root@hostname ~]# groups root
root : root bin daemon sys adm disk wheel

Solaris:

[root@hostname ~]# groups root
root other bin sys adm uucp mail tty lp nuucp daemon

A simple change of i=3 to i=1, and "Bob's your uncle"!

Thanks again,

  • Avron

blast - it's not so simple as that, either... I'm still digging at this one...

And maybe x[1] to $user as well ?

(Sorry, no Solaris around here - only windblows.)

tyler_durden

______________________________________________
"Only after disaster can we be resurrected."

Yeah, no.

I'm getting multiple lines for users that are actually groups. I'll approach this from another angle.

I've slightly modified my original scripts to do the following:

  1. Run this script on each of the unique hosts
#!/bin/sh
for user in `awk -F: '{print $1}' /etc/passwd`; do printf "$user:" ; groups $user ; done

The above script provides the results below:

root:root other bin sys adm uucp mail tty lp nuucp daemon
daemon:other bin adm
bin:bin sys
sys:sys
adm:adm sys tty lp
lp:lp
uucp:uucp
nuucp:nuucp
smmsp:smmsp
listen:adm
gdm:gdm
webservd:webservd
postgres:postgres
svctag:daemon
nobody:nobody
noaccess:noaccess
nobody4:nogroup
  1. Collect the data with this script to an appropriate directory:
for host in `cat hosts`; do ssh $host /tmp/myScript.sh >> $host; done
  1. Run a script to clean it up with results in the format of:
    $host:username:group
    $host:username:group2
    ...

I've tried mangling the script provided by Tyler, but it just doesn't work reliably. I will throw together a quick perl script to break it into a hash with array members. It's not as smooth as I'd like, but it will get me through this problem. I'll post the .pl here after lunch.

  • Avron

And so perl does the magic...

#!/usr/bin/perl -w
use strict;
use Getopt::Std;

my $dir        = "/path/to/data"; # base directory
my @file;
my @line;
my $line;
my @groups;
my $groups;

open(FILE, "<$dir/$ARGV[0]") or die "Cannot open $ARGV[0] for read :$!";
@file = <FILE>;
close( FILE );

foreach (@file)
{
   chomp;
   @line =  split(/\:/, $_);
   @groups = split(' ', $line[1]);
   foreach (@groups) {
      print "$ARGV[0]:$line[0]:$_\n";
   }
}