我需要另一个帮助,这是继续从bash中的嵌套括号中提取数据,
我的输入数据如下所示,具有多个块,我想放置一个逻辑来单独检查网络 VLAN 块,排除身份验证、网络主干、网络接口块。
auths remote {
roles {
admin {
role administrator
}
readonly {
role read-only
}
}
}
auths ldap system {
login-attribute uid
port 636
}
network vlan internal-vlan {
description "internal-use"
interfaces {
1.1 { }
1.2 { }
}
MTU {
1500
}
}
network vlan external-vlan {
description "external-use"
interfaces {
2.1 { }
2.2 { }
}
MTU {
1500
}
}
network vlan dummy-vlan {
description "dummy-use"
interfaces {
1.1 { }
}
}
network trunk {
description "none"
}
network interface 1.1 {
Status {
UP
}
}
network interface 1.2 {
Status {
UP
}
}
network interface 2.1 {
Status {
DOWN
}
}
network interface 2.2 {
Status {
UP
}
}
system update settings {
frequency monthly
}
我想要与以前类似的输出。我想我必须创建一个父函数并放置一个 if 逻辑来检查该块是否以“network vlan”开头,然后触发 proc 网络。
如果我可以放置一个 if 逻辑来检查字符串“network vlan”,然后触发一个过程,我想我可以关联其余的配置并在需要的地方创建新函数。
答案1
由于您的上一个问题要求 perl 解决方案,所以这里是一个相当简单的解决方案,除了匹配嵌套{...}
块所需的递归正则表达式之外,我已将其分离到变量 中$balanced
。这也允许它使用 3 次,一次匹配每个关键字network vlan
、interfaces
和后面的块MTU
。
#!/usr/bin/perl
use strict;
open(F,"datafile") or die;
my $data = join("",<F>);
my $balanced = qr/
( ( [^{}]*+
({ (?-2)* })?
)*
)/x;
while($data =~ m/network\s+vlan\s+([^ {]+)\s*{$balanced}/g){
my $vlan = $1;
my $body = $2;
$body =~ m/description\s*("[^\"]*")/;
my $desc = $1;
$body =~ m/interfaces\s*{$balanced}/;
my $intf = $1;
$intf =~ s/\s+/ /g;
my $mtu = 'none';
$mtu = $1 if($body =~ m/MTU\s*{$balanced}/);
$mtu =~ s/\s+/ /g;
print "$vlan, $desc,$intf,$mtu\n";
}
$balanced
一旦您匹配了块的开头,就会使用 ,并继续{
匹配任何不是{
或 的内容。后面可选地跟随,即返回 2 个括号的递归,以及,即。这是在里面使其成为可选的。我不是 Perl 专家,因此毫无疑问有一个更优化的版本。}
[^{}]*
{
}
{(?-2)*}
()?