Solved

Comparing substrings in two arrays

Posted on 2008-10-16
7
371 Views
Last Modified: 2012-05-05
Working on a script to get CDP neighbor and interface information from Cisco switches.  I'm using Net::SNMP (faster than using Net::Telnet::Cisco or an Expect script) to get OID string for interface name and pushing all names to array1.  Also using SNMP to get OID string for CDP neighbor and pushing all neighbors to array2.  Each of the returned strings contains an interface index number, separated from the text string by a ":", as follows:

@array1
10:3/1
11:3/2
12:3/3
13:3/4
14:3/5

@array2
10:TBA05271343(RICHM-CA-W80801)
11:TBA05240668(RICHM-CA-W80802)
90:RICHM-CA-N85601.ssa.gov
141:JAE062208G4(RICHM-CA-W8561A)

I'd like to match up the interface name with the neighbor name by matching on the interface index.  Is there a good way to compare two arrays and look for matches on substrings?  I've been trying various methods like nesting foreach loops to search for matching strings, with no luck.
Thanks - Rich
0
Comment
Question by:sol10
7 Comments
 
LVL 39

Expert Comment

by:Adam314
ID: 22733970
The way to do this is with a hash.  You could probably skip the creating of one of the arrays, depending on how they are created, but going from your two arrays:

my @array1 = qw(10:3/1 11:3/2 12:3/3 13:3/4 14:3/5);

my @array2 = qw[10:TBA05271343(RICHM-CA-W80801) 11:TBA05240668(RICHM-CA-W80802) 90:RICHM-CA-N85601.ssa.gov 141:JAE062208G4(RICHM-CA-W8561A)];
 

my %hash2;

foreach (@array2) {

	my @f = split/:/;

	$hash2{$f[0]} = $f[1];

}
 

foreach (@array1) {

	my $index = (split/:/)[0];

	my $name = ($hash2{$index} or "*no name*");

	print "$_ = $name\n";

}

Open in new window

0
 

Author Comment

by:sol10
ID: 22734703
Thanks for the response.  Not a big programmer, so it took me a few minutes to understand what you did..  Please bear with me while I type out what I believe your code is doing: you took each element from @array2 and created another array (@f) by splitting each element from @array2 at the colon.  Then you created a hash using the split information - the key being element $f[0] (the index number) and the value being element $f[1] (the CDP neighbor name).  Then you split each element of @array1 at the colon and created variable $index using the interface index number.  Variable $name is equal to the value of key hash2{index number}, or "*no name* if there is no matching key in the hash.  Then print the output.  Am I close?

This is very close!  The output from your code looks like this:

10 = *no name*
: = *no name*
TBA05271343(SSA-RICHM-CA-W80801) = *no name*

I should have been more descriptive in the initial question.  What I was looking for was something like this:

3/1 = TBA05271343(SSA-RICHM-CA-W80801)
3/2 = TBA05240668(SSA-RICHM-CA-W80802)
0
 
LVL 84

Expert Comment

by:ozo
ID: 22734882
@array1=qw(
10:3/1
11:3/2
12:3/3
13:3/4
14:3/5
);
@array2=qw(
10:TBA05271343(RICHM-CA-W80801)
11:TBA05240668(RICHM-CA-W80802)
90:RICHM-CA-N85601.ssa.gov
141:JAE062208G4(RICHM-CA-W8561A)
);
my %hash=map{split/:/,$_,2}@array1;
/(.*?):(.*)/ && $hash{$1} && print "$hash{$1} = $2\n" for @array2;

0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 17

Expert Comment

by:mjcoyne
ID: 22739220
Try Adam's code with this replacement:

foreach my $element (@array1) {
        my @index = split (/:/, $element);
        my $name = ($hash2{$index[0]} or "*no name*");
        print "$index[1] = $name\n";
}
0
 

Author Comment

by:sol10
ID: 22740884
Ozo and Adam314:  Output is fine when I use the static arrays as defined in your examples.  However, the output is incorrect when I use arrays populated as shown in the snippet.  Is there a more efficient way to do this, maybe by using hashes instead of arrays?  I could then do a $hash1{$key} cmp $hash2{$key} and push the values to an array?

my @array1;

my @array2;
 

foreach my $oid (oid_lex_sort(keys(%{$table}))) {

  if ($oid =~ m/(1.3.6.1.4.1.9.9.23.1.2.1.1.6.([\d]{1,3}))/) {

    #---this is ifIndex

    $intf_id = "$2";

    if ($table->{$oid}) {

      #---this is CDP neighbor name

      $neigh = $table->{$oid};

    } else {

      $neigh = "None";

    }

  }

  push @array2, $intf_id, ":", $neigh;

}
 

foreach my $oid (oid_lex_sort(keys(%{$table}))) {

  #---look at individual OIDs and get every ifIndex and ifName

  if ($oid =~ m/(1.3.6.1.2.1.31.1.1.1.1.([\d]{1,3}))/) {

    #---this is ifIndex

    $intf_id = "$2";

    if ($table->{$oid}) {

      #---this is ifName

      $if_name = $table->{$oid};

    } else {

      $if_name = "None";

    }

  }

  push @array1, $intf_id, ":", $if_name;

}

Open in new window

0
 
LVL 39

Accepted Solution

by:
Adam314 earned 500 total points
ID: 22741164

my %hash2;

 

foreach my $oid (oid_lex_sort(keys(%{$table}))) {

  if ($oid =~ m/(1.3.6.1.4.1.9.9.23.1.2.1.1.6.([\d]{1,3}))/) {

    #---this is ifIndex

    $intf_id = "$2";

    if ($table->{$oid}) {

      #---this is CDP neighbor name

      $neigh = $table->{$oid};

    } else {

      $neigh = "None";

    }

  }

  %hash2{$intf_id} = $neigh;

}

 

foreach my $oid (oid_lex_sort(keys(%{$table}))) {

  #---look at individual OIDs and get every ifIndex and ifName

  if ($oid =~ m/(1.3.6.1.2.1.31.1.1.1.1.([\d]{1,3}))/) {

    #---this is ifIndex

    $intf_id = "$2";

    if ($table->{$oid}) {

      #---this is ifName

      $if_name = $table->{$oid};

    } else {

      $if_name = "None";

    }

  }

  print "$if_name = " . (exists($hash2{$intf_id}) ? $hash2{$intf_id} : "*no name*") . "\n";

}

Open in new window

0
 

Author Closing Comment

by:sol10
ID: 31507216
Thanks for input and code!  -Rich
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Input from stdin for perl 6 108
PERL get the value for query 4 139
Removing file extension within a file. 4 88
Using Perl to parse rows 7 85
Many time we need to work with multiple files all together. If its windows system then we can use some GUI based editor to accomplish our task. But what if you are on putty or have only CLI(Command Line Interface) as an option to  edit your files. I…
Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now