Was wäre ein regulärer Ausdruck zum Erfassen von DHCP-Hostregistrierungsdatensätzen?

Was wäre ein regulärer Ausdruck zum Erfassen von DHCP-Hostregistrierungsdatensätzen?

Ich brauche einen regulären Ausdruck, um DHCP-Hostregistrierungsdatensätze zu erfassen

Ich muss einedhcpd.confDatei, für alle Hostreservierungen, und wenn möglich, diese in einer Datei oder einem Bash-Array erfassen. Wenn also eine Hostreservierung wie folgt definiert ist,

    host Service-Ethernet {
        hardware ethernet 11:11:11:11:11:11;
        fixed-address 192.168.0.3;
        option host-name "service";
    }

    host Service-Wifi {
        hardware ethernet 22:22:22:22:22:22;
        fixed-address 192.168.0.4;
    }

    host Test {
        hardware ethernet 33:33:33:33:33:33;
        fixed-address 192.168.0.5
        option host-name "test";
    }

Ausgabe in eine Datei oder ein Bash-Array ...

11:11:11:11:11:11, 192.168.0.3, service
22:22:22:22:22:22. 192.168.0.4,
, 192.168.0.5, test

Wenn einer der drei Parameter fehlt, lassen Sie ihn leer.

Auch wenn der Ausdruck zeilenweise angewendet werden muss, ist das noch akzeptabel. Ich kann den Ausdruck natürlich über ein Bash-Skript umschließen, das die Konfigurationsdatei zeilenweise liest.

Antwort1

Mit parse_dhcp.awkals

#!/usr/bin/env awk -f

function output() {
    printf "%s, %s, %s\n", hw, fa, opt
}

$1 == "host" {
    if (NR > 1) output()
    hw = fa = opt = ""
    next
}

{sub(/;$/, "")}
$1 == "hardware"      {hw = $NF}
$1 == "fixed-address" {fa = $NF}
$1 == "option"        {opt = $NF; gsub(/"/, "", opt)}

END {output()}

Dann

awk -f parse_dhcp.awk dhcp.conf

Noch undurchsichtiger ist, dass diese Datei eine gültige Tcl-Syntax aufweist, wir müssen also nur die DSL schreiben, damit wir die Datei als Tcl-Skript auswerten können:

#!/usr/bin/env tclsh

proc host {name data} {
    global vars
    array set vars {hardware "" fixed-address "" option ""}
    eval $data
    puts "$vars(hardware), $vars(fixed-address), $vars(option)"
}

proc unknown {cmd args} {
    global vars
    set vars($cmd) [lindex $args end]
}

set file [lindex $argv 0]
source $file

Und

tclsh parse_dhcp.tcl dhcp.conf

Antwort2

Die folgende einzeilige Perl-Ausgabe scheint fast das auszugeben, was Sie möchten:

perl -ane 'print $F[-1] =~ s/[";]//gr unless /[{}]/; print /^$/ ? "\n" : " "'

ich fürchte jedoch, dass die Eingabe Abschnitte enthalten kann, die Sie vollständig überspringen möchten. Daher sind weitere Optimierungen erforderlich:

perl -ane 'if (/host/ .. /}/) {
               print $F[-1] =~ s/[";]//gr unless /[{}]/;
               print /}/ ? "\n" : " "
           }'

was bedeutet

  • Wenn wir uns zwischen Zeilen befinden, die hostund enthalten }, verarbeiten wir die Eingabe, andernfalls überspringen wir sie.
  • Wenn die aktuelle Zeile keine Anführungszeichen enthält, drucken wir das letzte Wort aus, nachdem wir Semikolons und Anführungszeichen entfernt haben
  • Wenn die Zeile eine schließende geschweifte Klammer enthält, drucken wir eine neue Zeile, andernfalls ein Leerzeichen.

Antwort3

Ich habe gesehen, dass die Leute mit unterschiedlichen und kreativen Lösungen geantwortet haben. Als Regex-Enthusiast habe ich versucht, bei Bedarf mit regulären Ausdrücken zu antworten.

Es stellt sich heraus, dass Ihr Beispiel aufgrund des fehlenden Semikolons in der Testanweisung des Hosts kein wohlgeformtes Dokument ist.

Sie sehen, hier liegt ein Syntaxfehler vor, der zwei völlig sinnvolle Ausdrücke innerhalb der Anweisung „Host Test“ ungültig macht: „Fixed-Address“ und „Option“.

Wenn Sie mit wohlgeformten Dokumenten arbeiten möchten und dieses Beispiel ein Fehler war, können Sie Folgendes verwenden:

host\s+[\w\-]+\s*\{(\s+hardware\s+ethernet\s+(([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2});)?(\s*fixed-address\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3});)?(\s*option\s+host-name\s+"(.*?)";)?\s*\}

Die Ersetzungszeichenfolge lautet dann:

\2, \5, \7

Wenn Sie hingegen Dokumente adressieren müssen, in denen Semikolons fehlen, setzen Sie nach jedem Semikolon, das Sie optional machen möchten, ein Fragezeichen.

Sie können Ihre Optionen testen inhttps://regex101.com/

Sagen Sie mir Bescheid, wenn ich einen Fehler gemacht habe. Viel Glück.

verwandte Informationen