Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Regular expression assistance

by agentorange (Sexton)
on Dec 07, 2012 at 15:38 UTC ( #1007760=perlquestion: print w/replies, xml ) Need Help??
agentorange has asked for the wisdom of the Perl Monks concerning the following question:

Struggling a bit with regular expressions and hopefully someone can help.
Parsing some Cisco CDP output and my string equals below:
$cdp = "Device-ID (0x01), length: 44 bytes: 'my-switch-name' Address (0x02), length: 13 bytes: IPv4 (1) Port-ID (0x03), length: 16 bytes: 'Ethernet101/1/20' Capability (0x04), length: 4 bytes: (0x00000228): L2 Switch, IGMP snoo +ping Version String (0x05), length: 66 bytes: Cisco Nexus Operating System (NX-OS) Software, Version 5.2(1)N1(3) Platform (0x06), length: 11 bytes: 'N5K-C5596UP' Native VLAN ID (0x0a), length: 2 bytes: 911 AVVID trust bitmap (0x12), length: 1 byte: 0x00 AVVID untrusted ports CoS (0x13), length: 1 byte: 0x00 Duplex (0x0b), length: 1 byte: full MTU (0x11), length: 4 bytes: 1500 bytes System Name (0x14), length: 11 bytes: 'my-switch-name' System Object ID (not decoded) (0x15), length: 14 bytes: 0x0000: 060c 2b06 0104 0109 0c03 0103 880e Management Addresses (0x16), length: 13 bytes: IPv4 (1) Physical Location (0x17), length: 13 bytes: 0x00/snmplocation"

If using ksh and awk something like this would work:
VLAN=`echo $cdp | awk '/0x0a/ { print $8 }'`
And set VLAN to 911. But I just cannot see how to do it with Perl even though it is almost certainly ridiculously straight forward. my @switch = ( $cdp =~  m/0x01/ ); Isn't working and any assistance gratefully received.

Replies are listed 'Best First'.
Re: Regular expression assistance
by kennethk (Abbot) on Dec 07, 2012 at 15:48 UTC
    For me, the code print "yes\n" if $cdp =~ /0x01/; prints yes which means that your regular expression is valid. Can you show us a little more surrounding code? What do you expect to find in your array when you are done? Mine contains a 1, because that's what m// returns on a successful match.

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.


      Sorry didn't explain it fully but whilst I can pattern match ok I cannot see how to pattern match and pull out the 8th field in the line of which <space> is the separator char.
        Okay, much better. Assuming you want to do this in the midst of a script and not just piping one liners about, I would use more operations rather than be super sparse on characters. First, since you have a string that is internally-delimited by newlines, you can use . to match any character that is not a new line. This means you can actually grab your line using $cdp =~  m/(.*0x01.*)/, storing the line in $1. You could then split that on whitespace and grab the 8th field with (split /\s+/, $1)[7]. So collecting all your 8th field matches:
        my @switch; while ($cdp =~ m/(.*0x01.*)/g) { push @switch, (split /\s+/, $1)[7]; }
        If this is not your intent and the way forward is unclear, post explicit desired output so the goal is clear.

        #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Re: Regular expression assistance
by jwkrahn (Monsignor) on Dec 07, 2012 at 16:06 UTC
    VLAN=`echo $cdp | awk '/0x0a/ { print $8 }'` VLAN=`echo $cdp | perl -lane'/0x0a/ && print $F[7]'`
Re: Regular expression assistance
by DanEllison (Beadle) on Dec 07, 2012 at 16:08 UTC
    Assuming $cdp is piped into perl, try:
    while (<>) { if (/Native VLAN ID \(0x0a\), length: (\d+) bytes: (\d+)/ +) { print "$2\n"; }}

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1007760]
Approved by mbethke
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2017-06-24 10:37 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (557 votes). Check out past polls.