또 다른 도움이 필요합니다. 계속해야 합니다.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 네트워크를 트리거해야 한다고 생각합니다.
문자열 "network vlan"을 확인한 다음 프로세스를 트리거하는 if 논리를 넣을 수 있다면 나머지 구성을 상호 연관시키고 필요한 곳에 새 기능을 생성할 수 있을 것 같습니다.
답변1
이전 질문에서 Perl 솔루션을 요청했으므로 여기에 {...}
변수로 분리한 중첩 블록과 일치하는 데 필요한 재귀 정규 표현식을 제외하고는 상당히 간단한 솔루션이 있습니다 $balanced
. 이를 통해 각 키워드 network vlan
와 interfaces
다음 블록을 일치시키기 위해 한 번씩 총 3번 사용할 수 있습니다 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
블록의 시작 부분을 일치시키면 를 사용하고 or가 {
아닌 항목을 계속해서 일치시킵니다 {
. 선택적으로 2개의 괄호를 반환하는 재귀가 뒤따릅니다. 이것은 선택 사항으로 내부에 있습니다. 저는 Perl 전문가가 아니기 때문에 의심할 여지 없이 더 최적화된 버전이 있습니다.}
[^{}]*
{
}
{(?-2)*}
()?