• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 396
  • Last Modified:

Comparing substrings in two arrays

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
sol10
Asked:
sol10
1 Solution
 
Adam314Commented:
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
 
sol10Author Commented:
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
 
ozoCommented:
@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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
mjcoyneCommented:
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
 
sol10Author Commented:
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
 
Adam314Commented:

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
 
sol10Author Commented:
Thanks for input and code!  -Rich
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now