使用perl

时间:2015-12-09 06:09:44

标签: regex perl replace line config

我正在开发一个基于perl的项目。我有一个字符串形式的设备配置。我想使用正则表达式替换所有行配置块和其他模板。

我的设备配置中有4种类型的线路配置: -

  1. line vty

  2. 行控制台或行控制

  3. 行模板

  4. 行默认

  5. 所以我想用我自己的一组行替换完整的行配置块。

    示例: -

    $config = "enable password xyz
    enable secret 4 tnhtc92DXBhelxjYk8LWJrPV36S2i4ntXrpb4RFmfqY
    ip classless
    ip subnet-zero
    no ip domain lookup
    line vty 0 7
     transport input ssh telnet
     exec-timeout 720 0
     password xyz
     login
    line vty 0 8
     exec-timeout 720 0
    line con 0
     password xyz
    !
    line template vty
    timestamp
    exec-timeout 720 0
    !
    line template vty
    timestramp
    line console
    exec-timeout 0 0
    !";
    

    通常在每个行配置块之后都会有一个感叹号作为分隔符,但可能会出现一个新行,所以我也需要处理它。

    我正在考虑的方法是检查配置中的字线并检查直到! (感叹号作为分隔符)。

    我尝试了以下代码: -

    my $ios_line_vty_config = "line vty 0 4\ntransport input ssh telnet\nexec-timeout 720 0\npassword abc\nlogin local\n!\n";
    
    my $sub_os_type = "IOSv";
    
    my $vty_flag = 0;
    
    my @config_lines = split /\n/, $node_config;
    
    for my $line(@config_lines){
    
        if (!$vty_flag && $line =~ /^line\s+vty.*/){
              $vty_flag = 1;
              print "\nline vty Matched:: Remove line---> $line \n";
              $line = '';
              next;
           }
           print "flag = $vty_flag\n";
           if ($vty_flag){
    
              if($line =~ /!|line/){
                print "line = $line\n";
    
                if ($sub_os_type eq "IOSv"){
                  $line = $ios_line_vty_config.$line;
                }
                print "\nReplaced Line ---------> $line \n";
                $vty_flag = 0;
              }
              else {
              print "\nRemoved Line ---------> \n\n$line \n";
              print "\nsub_os_type :: $sub_os_type\n";
              $line = '';
            }
           }
    
    }
    

    我该怎么做?请帮帮我.. !!!

1 个答案:

答案 0 :(得分:1)

我发现有时候编写代码完全可以解释问题。如果我理解正确,你想重写一些包含“line”块的行。有些行块是“行vty”块,你想用其他东西替换它们的内容。当你读到一个时,你就到了一个街区的尽头!或者新行块的开头。这是你的代码重写了一点,以符合我对问题的理解,并使用你的$ config标量控制行:

#!/usr/bin/perl -w
use strict;
sub printBlock($$); #declare sub taking 2 parameters
my $config = "enable password xyz
enable secret 4 tnhtc92DXBhelxjYk8LWJrPV36S2i4ntXrpb4RFmfqY
ip classless
ip subnet-zero
no ip domain lookup
line vty 0 7
 transport input ssh telnet
 exec-timeout 720 0
 password xyz
 login
line vty 0 8
 exec-timeout 720 0
line con 0
 password xyz
!
line template vty
timestamp
exec-timeout 720 0
!
line template vty
timestramp
line console
exec-timeout 0 0
!";

print "$config\n========== old above ============= new below =================\n";
# DEBUG adding * to the start of lines so replacements are easy to see....
my $ios_line_vty_config = "*line vty 0 4\n*transport input ssh telnet\n*exec-timeout 720 0\n*password abc\n*login local\n*!\n";
my @config_lines = split(/\n/, $config);
my $block = "";
for my $line (@config_lines)
{
    $line =~ s/\s+$//; # remove trailing white space - make consistent
    if ($line =~ m/^line/) #start of block
    {
        printBlock($block, $ios_line_vty_config);
        $block = "$line\n";
    }
    elsif ($line =~ m/^!?$/) # ! or empty line signals end of block
    {
        $block .= "$line\n";
        printBlock($block, $ios_line_vty_config);
        $block = ""; #reset
    }
    elsif ($block) # in block
    {
        $block .= "$line\n";
    }
    else # outside of a block
    {
        print "$line\n";
    }
}
printBlock($block, $ios_line_vty_config);

sub printBlock($$)
{
    my $block = shift;
    my $replacement = shift;
    #decide here if replacing block ...
    $block = $replacement if ($block =~ m/line\s+vty/s); # replace block if it is a "line vty" block...
    print $block if ($block);
}

这就是我看到的输出:注意我把*放在替换行的前面,这样就更容易调试。

schumack@daddyo2 12-18T0:45:59 312> ./test.pl
enable password xyz
enable secret 4 tnhtc92DXBhelxjYk8LWJrPV36S2i4ntXrpb4RFmfqY
ip classless
ip subnet-zero
no ip domain lookup
line vty 0 7
 transport input ssh telnet
 exec-timeout 720 0
 password xyz
 login
line vty 0 8
 exec-timeout 720 0
line con 0
 password xyz
!
line template vty
timestamp
exec-timeout 720 0
!
line template vty
timestramp
line console
exec-timeout 0 0
!
========== old above ============= new below =================
enable password xyz
enable secret 4 tnhtc92DXBhelxjYk8LWJrPV36S2i4ntXrpb4RFmfqY
ip classless
ip subnet-zero
no ip domain lookup
*line vty 0 4
*transport input ssh telnet
*exec-timeout 720 0
*password abc
*login local
*!
*line vty 0 4
*transport input ssh telnet
*exec-timeout 720 0
*password abc
*login local
*!
line con 0
 password xyz
!
line template vty
timestamp
exec-timeout 720 0
!
line template vty
timestramp
line console
exec-timeout 0 0
!

我认为有两个线块替换是您正在寻找的。