Perl中的递归变量扩展
迁移后,我需要扩展ASA访问列表以供参考。 ASA现在不存在了,我想扩展对象组引用以验证我们捕获的所有预期访问。 我有一个使用4个对象组的ACL行的工作想法。 我的问题是ACL可能有0-4个对象组引用,我需要一个循环来运行和处理每个可能的组合。 我可以为每个可能的组合编写一个循环,但我知道必须有一种更优雅的方式 我已经有了单独扩展和存储对象组的代码,但是在线替换它们是一个挑战 谢谢你的时间和考虑Perl中的递归变量扩展,perl,Perl,迁移后,我需要扩展ASA访问列表以供参考。 ASA现在不存在了,我想扩展对象组引用以验证我们捕获的所有预期访问。 我有一个使用4个对象组的ACL行的工作想法。 我的问题是ACL可能有0-4个对象组引用,我需要一个循环来运行和处理每个可能的组合。 我可以为每个可能的组合编写一个循环,但我知道必须有一种更优雅的方式 我已经有了单独扩展和存储对象组的代码,但是在线替换它们是一个挑战 谢谢你的时间和考虑 @line = ('access-list','vlan_in','extended','permi
@line = ('access-list','vlan_in','extended','permit','object-group','ob1','object-group','ob2','object-group','ob3','object-group','ob4');
# @line = ('access-list','vlan_in','extended','permit','object-group','ob1','object-group','ob2','object-group','ob3','eq','53');
# @line = ('access-list','vlan_in','extended','permit','object-group','ob1','host','30.0.0.30','object-group','ob2','eq','23');
# @line = ('access-list','vlan_in','extended','permit','tcp','host','40.0.0.10','object-group','ob1','eq 80');
$OG{'ob1'} = ['tcp','udp'];
$OG{'ob2'} = ['10.0.0.10', '10.0.0.20'];
$OG{'ob3'} = ['20.0.0.15', '20.0.0.25'];
$OG{'ob4'} = ['eq 22', 'eq 443'];
foreach $ins4 (@{$OG{ob4}}) {
foreach $ins1 (@{$OG{ob1}}) {
foreach $ins2 (@{$OG{ob2}}) {
foreach $ins3(@{$OG{ob3}}) {
$buffer = "";
foreach $element (@line) {
if($element =~ /object-group/) { next; }
$buffer = $buffer . ' ' . $element;
}
$buffer =~ s/ob1/$ins1/;
$buffer =~ s/ob2/$ins2/;
$buffer =~ s/ob3/$ins3/;
$buffer =~ s/ob4/$ins4/;
print "$buffer\n";
}
}
}
}
(Current Output)
access-list vlan_in extended permit tcp 10.0.0.10 20.0.0.15 eq 22
access-list vlan_in extended permit tcp 10.0.0.10 20.0.0.25 eq 22
access-list vlan_in extended permit tcp 10.0.0.20 20.0.0.15 eq 22
access-list vlan_in extended permit tcp 10.0.0.20 20.0.0.25 eq 22
access-list vlan_in extended permit udp 10.0.0.10 20.0.0.15 eq 22
access-list vlan_in extended permit udp 10.0.0.10 20.0.0.25 eq 22
access-list vlan_in extended permit udp 10.0.0.20 20.0.0.15 eq 22
access-list vlan_in extended permit udp 10.0.0.20 20.0.0.25 eq 22
access-list vlan_in extended permit tcp 10.0.0.10 20.0.0.15 eq 443
access-list vlan_in extended permit tcp 10.0.0.10 20.0.0.25 eq 443
access-list vlan_in extended permit tcp 10.0.0.20 20.0.0.15 eq 443
access-list vlan_in extended permit tcp 10.0.0.20 20.0.0.25 eq 443
access-list vlan_in extended permit udp 10.0.0.10 20.0.0.15 eq 443
access-list vlan_in extended permit udp 10.0.0.10 20.0.0.25 eq 443
access-list vlan_in extended permit udp 10.0.0.20 20.0.0.15 eq 443
access-list vlan_in extended permit udp 10.0.0.20 20.0.0.25 eq 443
我可以强制执行此操作,但希望得到一些灵感,而不是过度重复代码。我可以为每个场景编写单独的循环,但我希望以更优雅的方式获得一些灵感
(if 3 occurrences of ob#)
# @line = ('access-list','vlan_in','extended','permit','object-group','ob1','object-group','ob2','object-group','ob3','eq','53');
foreach $ins1 (@{$OG{ob1}}) {
foreach $ins2 (@{$OG{ob2}}) {
foreach $ins3(@{$OG{ob3}}) {
$buffer = "";
foreach $element (@line) {
if($element =~ /object-group/) { next; }
$buffer = $buffer . ' ' . $element;
}
$buffer =~ s/ob1/$ins1/;
$buffer =~ s/ob2/$ins2/;
$buffer =~ s/ob3/$ins3/;
print "$buffer\n";
}
}
}
(if 2 occurrences of ob#)
# @line = ('access-list','vlan_in','extended','permit','object-group','ob1','host','30.0.0.30','object-group','ob2','eq','23');
foreach $ins1 (@{$OG{ob1}}) {
foreach $ins2 (@{$OG{ob2}}) {
$buffer = "";
foreach $element (@line) {
if($element =~ /object-group/) { next; }
$buffer = $buffer . ' ' . $element;
}
$buffer =~ s/ob1/$ins1/;
$buffer =~ s/ob2/$ins2/;
print "$buffer\n";
}
}
(if 1 occurrence of ob#)
# @line = ('access-list','vlan_in','extended','permit','tcp','host','40.0.0.10','object-group','ob1','eq 80');
foreach $ins1 (@{$OG{ob1}}) {
$buffer = "";
foreach $element (@line) {
if($element =~ /object-group/) { next; }
$buffer = $buffer . ' ' . $element;
}
$buffer =~ s/ob1/$ins1/;
print "$buffer\n";
}
您要查找的是%OG中值的叉积。去营救。下面的代码用于创建交叉乘积
use Set::Product qw[ product ];
my @line = (
'access-list', 'vlan_in', 'extended', 'permit',
'object-group', 'ob1', 'object-group', 'ob2',
'object-group', 'ob3', 'object-group', 'ob4'
);
# same order as things fed to product
my @placeholders = qw[ ob1 ob2 ob3 ob4 ];
product {
# for efficiency, this should be done outside of this loop
my $buffer = join( ' ', grep { !/object-group/ } @line );
# product places the values in @_; shift them off in order
$buffer =~ s/$_/shift()/ge for @placeholders;
print $buffer . "\n";
}
[ 'tcp', 'udp' ],
[ '10.0.0.10', '10.0.0.20' ],
[ '20.0.0.15', '20.0.0.25' ],
[ 'eq 22', 'eq 443' ]
;
导致
access-list vlan_in extended permit tcp 10.0.0.10 20.0.0.15 eq 22
access-list vlan_in extended permit tcp 10.0.0.10 20.0.0.15 eq 443
access-list vlan_in extended permit tcp 10.0.0.10 20.0.0.25 eq 22
access-list vlan_in extended permit tcp 10.0.0.10 20.0.0.25 eq 443
access-list vlan_in extended permit tcp 10.0.0.20 20.0.0.15 eq 22
access-list vlan_in extended permit tcp 10.0.0.20 20.0.0.15 eq 443
access-list vlan_in extended permit tcp 10.0.0.20 20.0.0.25 eq 22
access-list vlan_in extended permit tcp 10.0.0.20 20.0.0.25 eq 443
access-list vlan_in extended permit udp 10.0.0.10 20.0.0.15 eq 22
access-list vlan_in extended permit udp 10.0.0.10 20.0.0.15 eq 443
access-list vlan_in extended permit udp 10.0.0.10 20.0.0.25 eq 22
access-list vlan_in extended permit udp 10.0.0.10 20.0.0.25 eq 443
access-list vlan_in extended permit udp 10.0.0.20 20.0.0.15 eq 22
access-list vlan_in extended permit udp 10.0.0.20 20.0.0.15 eq 443
access-list vlan_in extended permit udp 10.0.0.20 20.0.0.25 eq 22
access-list vlan_in extended permit udp 10.0.0.20 20.0.0.25 eq 443
我不明白代码有什么问题,或者你还想做什么?但是,事实上,我不知道您的ASA/ACL/object groups/etc问题。我提供的示例目前有效。我希望找到另一种方法来处理那些不需要为每个场景编写单独的foreach循环就可以替换不到4次的行。我提供的其他@line数组是examplesOK。所以你的@行有ob1到ob4,或者可能不是全部;如果其中一些缺少regex s//,那么它们对$buffer没有任何作用。这就是你所说的可以有少于4个替换的意思吗?我看到的一个问题是ob4必须排在最后——并且在那里——因为它的正则表达式是唯一一个没有尾随空格的。如果这是唯一的问题,那么就让空格成为可选的,或者用字符串结尾的锚点进行替换。在我这方面,它是有效的。perl 5.26.0差点忘了返回并感谢您。这正是我要找的。