Extrahieren Sie Daten aus mehreren verschachtelten Klammern in TCL

Extrahieren Sie Daten aus mehreren verschachtelten Klammern in TCL

Ich brauche noch eine Hilfe, dies ist eine Fortsetzung vonExtrahieren Sie Daten aus den verschachtelten Klammern in Bash,

Ich habe Eingabedaten wie unten mit mehreren Blöcken und möchte eine Logik einfügen, um nur nach Netzwerk-VLAN-Blöcken zu suchen und die Blöcke „Authentifizierung“, „Netzwerk-Trunk“ und „Netzwerkschnittstelle“ auszuschließen.

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
}

Ich möchte eine ähnliche Ausgabe wie zuvor. Ich denke, ich muss eine übergeordnete Funktion erstellen und eine if-Logik einfügen, um zu prüfen, ob der Block mit „Netzwerk-VLAN“ beginnt, und dann das Proc-Netzwerk auslösen.

Wenn ich eine IF-Logik einfügen kann, um nach der Zeichenfolge „Netzwerk-VLAN“ zu suchen und dann einen Prozess auszulösen, denke ich, dass ich dies auf die restlichen Konfigurationen anwenden und bei Bedarf neue Funktionen erstellen kann.

Antwort1

Da Sie in Ihrer letzten Frage nach Perl-Lösungen gefragt haben, ist hier eine, die ziemlich einfach ist, mit Ausnahme des rekursiven regulären Ausdrucks, der zum Abgleichen verschachtelter {...}Blöcke erforderlich ist und den ich in die Variable ausgelagert habe $balanced. Dadurch kann sie auch dreimal verwendet werden, einmal zum Abgleichen des Blocks nach jedem der Schlüsselwörter network vlan, interfaces, und 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";
}

$balancedwird verwendet, sobald Sie die Eröffnung eines Blocks abgeglichen haben {, und fährt mit allem fort, was nicht {oder }durch Verwendung abgeglichen wird [^{}]*. Darauf folgt optional {, die Rekursion geht 2 Klammern zurück, und }, nämlich {(?-2)*}. Dies ist innerhalb, ()?um es optional zu machen. Ich bin kein Perl-Experte, also gibt es zweifellos eine optimalere Version davon.

verwandte Informationen