Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Please excuse my total ignorance, I'm a complete newbie to Perl </grovel>

I'm trying to parse a text file for several possible strings of text - if none of the stings are present on a line, I want the string output to another file.

Here's the output of the text file:

wwwroot\development\images\_notes\homepage_area_68_f4.jpg.mno Every +one R X wwwroot\development\images\_notes\homepage_area_68_f4.jpg.mno Domai +n\Webmins RWXD wwwroot\development\images\_notes\homepage_area_68_f4.jpg.mno Domai +n\Domain Admins all wwwroot\development\images\_notes\homepage_area_68_f4.jpg.mno Domai +n\user o
If a line contains eg. "Domain Admins all" or "Webmins all", I don't want it output to other file.

I'm trying this regexp:

while (<PERMSFILE>) { if ($_ !~ /Everyone +\t +R X/g | /Webmins +\t +all/g | /Domain Admins +\t +all/g | / o /g) { print SHORTPERMS $_; }
Which doesn't work - the only of the above text which should be output into the new file is the one containing "Webmins RXWD". The " +\t +" is because \s doesn't appear to work for the whitespace.

Edit by tye, change PRE to CODE around long lines

Replies are listed 'Best First'.
Re: RegExp query (hopefully simple)
by jasonk (Parson) on Apr 10, 2003 at 02:52 UTC

    A single pipe is a bitwise-or, it doesn't do what you are trying to do here (and even if it did, you want and, not or). And your ' +\t +' construct will only match whitespace, followed by a tab, followed by whitespace. I would do it something like this instead:

    while(<PERMSFILE>) { next if /Everyone\s+R X/; next if /Webmins\s+all/; next if /Domain Admins\s+all/; next if /\s+o\s+/; print SHORTPERMS; }

    The correct way to write the code you have though would be something like:

    while(<PERMSFILE>) { if( $_ !~ /Everyone\s+R X/ && $_ !~ /Webmins\s+all/ && $_ !~ /Domain Admins\s+all/ && $_ !~ / o /) { print SHORTPERMS $_; } }

    We're not surrounded, we're in a target-rich environment!
      Thanks muchly, jasonk - your first code snippet worked perfectly.

      And yes, I certainly understood the need for a not+OR kind of thing, I just couldn't find how to express it. Thanks for showing me that method as well.
Re: RegExp query (hopefully simple)
by The Mad Hatter (Priest) on Apr 10, 2003 at 02:56 UTC
    If I understood your question correctly, this should do the trick. I've modified your input data (only to make it consistantly spaces; you could change it back) and fixed your regex. When doing an or (||) or an and (&&), you need to specify what to compare it to every time (ex/ $foo =~ /$bar/ || $foo =~ /$bor/ || ...). Instead of doing this, I've done it in the regex.
    while (<DATA>) { print unless /(Everyone\s+R X|Webmins\s+all|Domain Admins\s+all|\s ++o\s*\z)/; } __DATA__ wwwroot\development\images\_notes\homepage_area_68_f4.jpg.mno Everyo +ne R X wwwroot\development\images\_notes\homepage_area_68_f4.jpg.mno Domain +\Webmins RWXD wwwroot\development\images\_notes\homepage_area_68_f4.jpg.mno Domain +\Domain Admins all wwwroot\development\images\_notes\homepage_area_68_f4.jpg.mno Domain +\user o
    That outputs
    wwwroot\development\images\_notes\homepage_area_68_f4.jpg.mno Domain +\Webmins RWXD
    which I assume is what you want?
      And that works perfectly, too, Mad Hatter. Looks like another case of "there's more than one way..." (I think I like this Perl-thing!). If I get output files that don't stick wierd tabbing in, this will be great.