O que seria um regex para capturar registros de registro de host DHCP?

O que seria um regex para capturar registros de registro de host DHCP?

Preciso de uma regex para capturar registros de registro de host DHCP

Eu preciso analisar através de umdhcpd.confarquivo, para todas as reservas de host e, se possível, capture-as em um arquivo ou matriz Bash. Portanto, se uma reserva de host for definida da seguinte forma,

    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";
    }

Saída para arquivo ou array Bash...

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

Se faltar um dos três parâmetros, deixe em branco.

Mesmo que a expressão deva ser aplicada linha por linha, isso ainda é aceitável. Posso agrupar a expressão por meio de um script Bash que lê o arquivo de configuração linha por linha, é claro.

Responder1

Com parse_dhcp.awkcomo

#!/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()}

então

awk -f parse_dhcp.awk dhcp.conf

Mais obscuramente, esse arquivo tem uma sintaxe Tcl válida, então só precisamos escrever a DSL para que possamos avaliar o arquivo como um script Tcl:

#!/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

e

tclsh parse_dhcp.tcl dhcp.conf

Responder2

As seguintes linhas Perl parecem quase produzir o que você deseja:

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

mas temo que a entrada possa conter seções que você deseja ignorar completamente, portanto, são necessários mais ajustes:

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

que significa

  • se estivermos entre linhas contendo hoste }, processamos a entrada, caso contrário, a ignoramos.
  • se a linha atual não contém curvas, imprimimos a última palavra, removendo ponto e vírgula e aspas duplas dela
  • se a linha contiver uma chave de fechamento, imprimimos uma nova linha, caso contrário, um espaço.

Responder3

Então, vi pessoas respondendo com soluções diferentes e criativas. Como entusiasta de regex, tentei responder com expressões regulares conforme necessário.

Acontece que sua amostra não é um documento bem formado devido ao ponto e vírgula ausente na instrução Host Test.

Veja, há um erro de sintaxe e isso invalida duas expressões perfeitamente razoáveis ​​​​dentro da instrução Host Test: endereço fixo e opção.

Se você deseja trabalhar com documentos bem formados e este exemplo foi um erro, então você pode usar:

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*\}

A string de substituição será então:

\2, \5, \7

Por outro lado, se você precisar endereçar documentos sem ponto e vírgula, coloque um ponto de interrogação após cada ponto e vírgula que você deseja tornar opcional.

Você pode testar suas opções emhttps://regex101.com/

Deixe-me saber se cometi um erro. Boa sorte.

informação relacionada