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

Folks: Been a while since I posted last, and I require a little pointing in the right direction - I am looking for a very simple solution, which removes lines that 'do not' match my criteria. I have a Expect script which dumps into a few generic devices, and logs out the session; however, I only want a few lines of the output. With the latter in mind - I have tried to fine tune my logging session for Expect; however, for some odd reason I must capture the entire session - otherwise nothing is captured. Due to the latter, I thought this would be a good exercise to learn more perl.

Expect session output = logout.txt

00:eb:99:33:bc:2c some string of text 00:eb:99:33:bc:2c Tx -.34 32423 00:eb:99:33:bc:2c null device log entries are empty - log service did not start 98:ab:34:12:ac:3c Rx critical Tx critical 00:eb:99:33:bc:2c device log entries are full 00:eb:99:33:bc:2c

The output is not formatted any particular way due to embedded firmware. What I am hoping to do is remove the lines, which do not have a MAC address in them. I am thinking I can do something like 0-1|a-e: 0-1|a-e: 0-1|a-e: 0-1|a-e:~ To match the MAC address format. Looking for direction on how to do this - I have no clue where to start, or what to look for. Thank you JW

Replies are listed 'Best First'.
Re: remove lines that do not match search pattern
by NetWallah (Canon) on Aug 03, 2015 at 14:24 UTC
    From "perldoc perlop":

    Binary "!~" is just like "=~" except the return value is negated in th +e logical sense.
    So - use your pattern, and negate the match.

    Try this pattern:

    !~/(:?[\da-f]{2}:){5}[\da-f]{2}/
    or better, Regexp::Common::net provides built-in regex matching for mac addresses.

            Clarity: it's like that one thing that is not the other thing, except for when it is.

      Thank you for your suggestions and direction on the regex pattern. I was able to get something working, and the ability to parse through my files.

Re: remove lines that do not match search pattern
by ww (Archbishop) on Aug 03, 2015 at 14:17 UTC

    Capture lines that 'do not' (  !~ ) match your regex...
    or
    capture lines that are not excluded by  unless =~ your regex

    Or did you mean you want another way to write the regex (which should be enclosed by code tags for readability).

      I only want to save the lines that match - meaning that only have a MAC address in the line, and delete all other data.

      thanks!

Re: remove lines that do not match search pattern
by pme (Monsignor) on Aug 03, 2015 at 14:12 UTC

      Thanks for the suggestions as to using Expect. I will take a look at this

      Just for my own knowledge - what do I call what I am trying to do with 0-9|a-e:0-9|a-e?

        ... what do I call what I am trying to do with 0-9|a-e:0-9|a-e?

        Assuming you're actually working with  [0-9]|[a-e]:[0-9]|[a-e] (please use  <code> ... </code> tags in future; please see Writeup Formatting Tips, Markup in the Monastery), it can be explained as:

        c:\@Work\Perl\monks>perl -wMstrict -le "use YAPE::Regex::Explain; ;; my $rx = qr{ [0-9] | [a-e]:[0-9] | [a-e] }xms; print YAPE::Regex::Explain->new($rx)->explain; " The regular expression: (?msx-i: [0-9] | [a-e]:[0-9] | [a-e] ) matches as follows: NODE EXPLANATION ---------------------------------------------------------------------- (?msx-i: group, but do not capture (with ^ and $ matching start and end of line) (with . matching \n) (disregarding whitespace and comments) (case-sensitive): ---------------------------------------------------------------------- [0-9] any character of: '0' to '9' ---------------------------------------------------------------------- | OR ---------------------------------------------------------------------- [a-e] any character of: 'a' to 'e' ---------------------------------------------------------------------- : ':' ---------------------------------------------------------------------- [0-9] any character of: '0' to '9' ---------------------------------------------------------------------- | OR ---------------------------------------------------------------------- [a-e] any character of: 'a' to 'e' ---------------------------------------------------------------------- ) end of grouping ----------------------------------------------------------------------
        See YAPE::Regex::Explain for regexes of Perl version 5.6 or before.


        Give a man a fish:  <%-(-(-(-<

        OT

        Filtering with Tcl/expect:

        #!/usr/bin/expect while {[gets stdin line] >= 0} { if {[regexp {([[:xdigit:]]{2}:?){6}} $line]} { puts $line } }
Re: remove lines that do not match search pattern
by Anonymous Monk on Aug 03, 2015 at 15:10 UTC
    grep -v ...
Re: remove lines that do not match search pattern
by GotToBTru (Prior) on Aug 04, 2015 at 13:09 UTC

    Do you really want to remove lines that don't have a MAC address, or do you want to keep lines that do?

    I don't have Expect installed, so I can't test this, but looking at the documentation, it appears the $obj->expect($cmd,@params) and $obj->matchlist() contain the functionality you need. @params needs to contain a single entry, a regex that matches MAC addresses. matchlist() will return an array(?) of matching lines from the output of $cmd.

    Dum Spiro Spero