Awk Question

Ben Walton bdwalton-Re5JQEeQqe8AvxtiuMwx3w at public.gmane.org
Mon Oct 29 19:13:07 UTC 2012


Hi William,

On Mon, Oct 29, 2012 at 5:44 PM, William Weaver
<williamdweaver-Re5JQEeQqe8AvxtiuMwx3w at public.gmane.org> wrote:

> So I'm still working on my awk skills. I'm trying to write a script that
> allows me to pase a csv file of user rights and get all users that have a
> specific right. Then using that list of users find all other rights those
> users have.
>
> ...snip...
>
> This gets me the list of all users with Delete and prints it for me. I've
> been tinkering with a few ways to iterate through the array but I can't seem
> to figure out how to do it. I think it requires two passes through the file,
> one to generate the user list and one to generate the rights list, but I'm
> kinda stuck. Anyone have any ideas.

Not to discourage you from learning something new, but my honest
advice is that in 2012, awk is typically _not_ the right tool for this
kind of thing.  Any/all of ruby/python/perl are perfectly suited to
this task and also provide many more abilities for larger scripts.
(eg: They're more useful to learn!)  The rule of thumb I apply to the
use of awk these days is that if you're doing more than pulling field
X,Y,Z, possibly with a filter condition, out of a stream you should
use a different tool.  An example of what I'm describing as the
ceiling for awk use might be pulling all users with /bin/sh as their
shell from /etc/passwd, listing username and gecos fields...

(Please ignore the above if you're learning for the sake of learning.)

Now, commenting generally on your approach with awk, if you skip
through the whole file looking only for a certain privilege, you'll be
restricting yourself to needing a second pass through the file.  What
you (likely) want to do instead is build two maps as you go through
the file.  The first mapping is privilege -> user, so store a list of
users that have privilege edit, delete, etc.  The second map, built at
the same time, is the reverse of that: user -> privilege.  Here is a
quick example I just banged out; The printing logic is ugly, but I
think it demonstrates what you're trying to do.

#!/usr/bin/awk -f

BEGIN { FS="," }

{
    Privs[$2,$1] = 1;
    Users[$1,$2] = 1;
}

END {
    for (u in Users) {
        split (u, parts, SUBSEP);
        if (parts[2] == "Delete") {
            print parts[1];
            for (p in Privs) {
                split(p, privparts, SUBSEP);
                if (privparts[2] == parts[1]) {
                    print privparts[1];
                }
            }
        }
    }
}

[I had to look up how multidimensional arrays in awk worked...nasty!]

Thanks
-Ben
-- 
---------------------------------------------------------------------------------------------------------------------------
Take the risk of thinking for yourself.  Much more happiness,
truth, beauty and wisdom will come to you that way.

-Christopher Hitchens
---------------------------------------------------------------------------------------------------------------------------
--
The Toronto Linux Users Group.      Meetings: http://gtalug.org/
TLUG requests: Linux topics, No HTML, wrap text below 80 columns
How to UNSUBSCRIBE: http://gtalug.org/wiki/Mailing_lists





More information about the Legacy mailing list