I really like Perlbotics suggestion about doing a relational database, and with SQLite, there's really no reason not to. Here's an initial stab at something you might want to try -- just plug in the actual paths for your group and passwd files.

The main point of this script is to load three tables (groups per server, users per server, users per group per server), so if you have a static set of files to read, you would just run this once, and then create a separate script to allow users to run queries on the tables (for users in particular groups, groups for a particular user, across all servers or on particular servers, etc).

I tacked on a global query to dump out the table contents after they're loaded, but if your data set is really huge, you might want to comment that out (or maybe add "limit 20" at the end of the select statement). You might want your tables to be defined differently as well.

#!/usr/bin/perl use strict; use warnings; use DBI; my $db = DBI->connect( "dbi:SQLite:dbname=SrvrGrpData","","" ); $db->do( "DROP TABLE IF EXISTS srvr_grp" ); $db->do( "DROP TABLE IF EXISTS srvr_usr" ); $db->do( "DROP TABLE IF EXISTS grp_usr" ); $db->do( "CREATE TABLE srvr_grp (srvrid varchar(40), grpname varchar(4 +0), grpnum int)" ); $db->do( "CREATE TABLE srvr_usr (srvrid varchar(40), usrname varchar(4 +0), usrnum int, defgrp int)" ); $db->do( "CREATE TABLE grp_usr (srvrid varchar(40), grpid int, usrnam +e varchar(40))" ); my $ins_grp = $db->prepare( "insert into srvr_grp (srvrid,grpname,grpn +um) values (?,?,?)" ); my $ins_gu = $db->prepare( "insert into grp_usr (srvrid,grpid,usrname) + values (?,?,?)" ); my $grp_path = "/path/to/group_files"; my $usr_path = "/path/to/passwd_files"; chdir $grp_path or die "chdir $grp_path: $!\n"; opendir( D, "." ) or die "opendir $grp_path: $!\n"; while ( my $f = readdir( D )) { open( F, "<", $f ) or do { warn " open failed on $f: $!\n"; next } +; my ( $srvr ) = ( $f =~ /^(\w+)/ ); while (<F>) { next if ( /^#/ ); chomp; my ( $gname, $skip, $gnum, $gmembers ) = split m{:}; $ins_grp->execute( $srvr, $gname, $gnum ); for my $u ( split m{,}, $gmembers ) { $ins_gu->execute( $srvr, $gnum, $u ); } } close F; } closedir D; $ins_grp->finish; $ins_gu->finish; my $ins_usr = $db->prepare( "insert into srvr_usr (srvrid,usrname,usrn +um,defgrp) values (?,?,?,?)" ); chdir $usr_path or die "chdir $usr_path: $!\n"; opendir( D, "." ) or die "opendir $usr_path: $!\n"; while ( my $f = readdir( D )) { open( F, "<", $f ) or do { warn " open failed on $f: $!\n"; next } +; my ( $srvr ) = ( $f =~ /^(\w+)/ ); while (<F>) { next if ( /^#/ ); chomp; my ( $uname, $unum, $dgrp ) = split m{:}; $ins_usr->execute( $srvr, $uname, $unum, $dgrp ); } close F; } closedir D; $ins_usr->finish; for my $table ( qw/srvr_grp srvr_usr grp_usr/ ) { print "\n== selecting all from $table: ==\n"; my $qsth = $db->prepare( "select * from $table" ); $qsth->execute; my $rows = $qsth->fetchall_arrayref; for my $row ( @$rows ) { print join( "\t", @$row ), "\n"; } }
No system calls at all, and setting up a nice set of parameterized queries (where a user just supplies a string that they're looking for in a given field) would be pretty quick and easy. Turn-around time on answering queries will be a lot faster with SQLite than what you'd get by scanning through all the group and passwd files for every query.

In reply to Re: Any way to do this without system calls? by graff
in thread Any way to do this without system calls? by walkingthecow

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.