简体   繁体   English

Mac地址上的Perl REGEX

[英]Perl REGEX on mac address

I am using the command "show mac-address-table dynamic" on a cisco switch via perl script. 我通过perl脚本在cisco交换机上使用命令“ show mac-address-table dynamic”。 The output for the same as is follows: 输出结果如下:

Legend: * - primary entry
    age - seconds since last seen
    n/a - not available

vlan   mac address     type    learn     age              ports
------+----------------+--------+-----+----------+--------------------------
*   14  782b.cb87.b085   dynamic  Yes          5   Gi4/39
*  400  0017.c59a.23aa   dynamic  Yes         15   Gi3/37
*  400  0017.c59a.23aa   dynamic  Yes          5   Gi1/27
*  400  0017.c50f.704d   dynamic  Yes          5   Gi13/19
*  400  0006.8b05.a915   dynamic  Yes         10   Gi5/29
*  400  c0ea.e414.2f29   dynamic  Yes         10   Gi3/37
*  400  0017.c53e.166d   dynamic  Yes          5   Gi1/12

I am writing a script such that it takes out only the mac address having initial first 4 figures such as 0017.c5 or 0006b or c0ea.e4. 我正在编写一个脚本,使其仅取出具有前4个初始数字的mac地址,例如0017.c5或0006b或c0ea.e4。 Also, it should display the number of times they are repeated. 另外,它应该显示重复的次数。 I tried by writing the below code: 我尝试编写以下代码:

for my $line (@ver) {
    if (my ($mac_addr) = $line =~ /((?:[0-9a-f]{4}\.){2}[0-9a-f]{4})/) {
        $mac_addr = $1;
        if ($mac_addr =~ m/^(0017.c5)[0-9a-f]{2}.[0-9a-f]{4}/ or $mac_addr =~ m/^(c0ea.e5)[0-9a-f]{2}.[0-9a-f]{4}/ or $mac_addr =~ m/^(0006.b)[0-9a-f]{3}.[0-9a-f]{4}/){
            push (@sonic_macaddr, $mac_addr);
            for $it (@sonic_macaddr){
                $uniq{$it}++;
            }
        }
    }
}
print (Dumper(\%uniq));

I am not getting the required results. 我没有得到所需的结果。 Please can somebody guide me where I am going wrong? 请有人可以指导我哪里出问题了吗? Thanks. 谢谢。

This match will always fail: 这场比赛将永远失败:

$mac_addr =~ m/^(0017.c5)[.]/

That looks for your desired prefix, followed by a period. 查找所需的前缀,后跟一个句点。 None of your mac address will have a period at the 8th character. 您的mac地址中的第8个字符都没有句号。

Perhaps the following reworking of your script will help you: 也许下面的脚本重做将对您有所帮助:

use strict;
use warnings;

my @ver = <DATA>;

my @mac_prefixes = qw(0017.c5 c0ea.e5 0006.b);
my $mac_prefixes = '(?:' . join('|', map quotemeta, @mac_prefixes) . ')';

my @sonic_macaddr;
my %uniq;

for my $line (@ver) {
    if (my ($mac_addr) = $line =~ /((?:[0-9a-f]{4}\.){2}[0-9a-f]{4})/) {
        $mac_addr = $1;
        if ($mac_addr =~ m/^($mac_prefixes)/){
            my $prefix = $1;
            push (@sonic_macaddr, $mac_addr);
            $uniq{$prefix}++;
        }
    }
}

use Data::Dump;
dd \%uniq;
dd \@sonic_macaddr;

__DATA__
Legend: * - primary entry
    age - seconds since last seen
    n/a - not available

vlan   mac address     type    learn     age              ports
------+----------------+--------+-----+----------+--------------------------
*   14  782b.cb87.b085   dynamic  Yes          5   Gi4/39
*  400  0017.c59a.23aa   dynamic  Yes         15   Gi3/37
*  400  0017.c59a.23aa   dynamic  Yes          5   Gi1/27
*  400  0017.c50f.704d   dynamic  Yes          5   Gi13/19
*  400  0006.8b05.a915   dynamic  Yes         10   Gi5/29
*  400  c0ea.e414.2f29   dynamic  Yes         10   Gi3/37
*  400  0017.c53e.166d   dynamic  Yes          5   Gi1/12

First you have problem with your regex. 首先,您的正则表达式有问题。 Just remove the [.] from the regex. 只需从正则表达式中删除[.]

Secondly, you are pushing the result into the @sonic_macaddr array and then increasing the $uniq for every match. 其次,将结果推入@sonic_macaddr数组,然后为每个匹配项增加$uniq It is giving you wrong count. 它给您计数错误。 So remove that portion. 因此,删除该部分。

Here is how your if block looks like after the modification. 这是修改后的if块外观。

if ($mac_addr =~ m/^(0017.c5)/ or $mac_addr =~ m/^(c0ea.e5)/ or $mac_addr =~ m/^(0006.b)/){
    $uniq{$mac_addr}++;
}

Output for your sample Data: 输出样本数据:

$VAR1 = {
      '0017.c53e.166d' => 1,
      '0017.c59a.23aa' => 2,
      '0017.c50f.704d' => 1
    };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM