我正在开发一个基于perl的项目。我有一个字符串形式的设备配置。我想使用正则表达式替换所有行配置块和其他模板。
我的设备配置中有4种类型的线路配置: -
line vty
行控制台或行控制
行模板
行默认
所以我想用我自己的一组行替换完整的行配置块。
示例: -
$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 = '';
}
}
}
我该怎么做?请帮帮我.. !!!
答案 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
!
我认为有两个线块替换是您正在寻找的。 p>