Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

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 2018-05-26 00:37 GMT
Find Nodes?
    Voting Booth?