¿Cuál sería una expresión regular para capturar registros de registro de host DHCP?

¿Cuál sería una expresión regular para capturar registros de registro de host DHCP?

Necesito una expresión regular para capturar registros de registro de host DHCP

Necesito analizar a través de undhcpd.confarchivo, para todas las reservas de host y, si es posible, capturarlos en un archivo o matriz Bash. Entonces, si una reserva de anfitrión se define de la siguiente manera,

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

Salida a archivo o matriz 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

Si falta uno de los tres parámetros, déjelo en blanco.

Incluso si la expresión debe aplicarse línea por línea, sigue siendo aceptable. Puedo ajustar la expresión mediante un script Bash que lee el archivo de configuración línea por línea, por supuesto.

Respuesta1

Como parse_dhcp.awksi

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

entonces

awk -f parse_dhcp.awk dhcp.conf

Más oscuramente, ese archivo tiene una sintaxis Tcl válida, por lo que solo necesitamos escribir el DSL para poder evaluar el archivo como un 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

y

tclsh parse_dhcp.tcl dhcp.conf

Respuesta2

Las siguientes líneas simples de Perl parecen casi generar lo que desea:

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

pero me temo que la entrada puede contener secciones que deseas omitir por completo, por lo que se necesitan más ajustes:

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

lo que significa

  • si estamos entre líneas que contienen hosty }, procesamos la entrada; de lo contrario, la omitimos.
  • Si la línea actual no contiene rizos, imprimimos la última palabra, eliminando el punto y coma y las comillas dobles.
  • si la línea contiene una llave de cierre, imprimimos una nueva línea; de lo contrario, un espacio.

Respuesta3

Entonces vi gente respondiendo con soluciones diferentes y creativas. Como entusiasta de las expresiones regulares, intenté responder con expresiones regulares según fuera necesario.

Resulta que su muestra no es un documento bien formado debido a que falta un punto y coma en la declaración de prueba del host.

Verá, hay un error de sintaxis allí que invalida dos expresiones perfectamente razonables dentro de la prueba del host de declaración: dirección fija y opción.

Si desea trabajar con documentos bien formados y este ejemplo fue un error, puede utilizar:

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

La cadena de sustitución será entonces:

\2, \5, \7

Por otro lado, si necesita abordar documentos a los que les falta punto y coma, coloque un signo de interrogación después de cada punto y coma que necesite convertir en opcional.

Puede probar sus opciones enhttps://regex101.com/

Déjame saber si cometí un error. Buena suerte.

información relacionada