捕获 DHCP 主机注册记录的正则表达式是什么?

Sch*_*chi 1 dhcp regular-expression

我需要一个正则表达式来捕获 DHCP 主机注册记录

我需要通过dhcpd.conf文件解析所有主机保留,如果可能的话,将其捕获到文件或 Bash 数组中。因此,如果主机预留定义如下,

    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";
    }
Run Code Online (Sandbox Code Playgroud)

输出到文件或 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
Run Code Online (Sandbox Code Playgroud)

如果缺少三个参数之一,请将其留空。

即使表达式必须逐行应用,这仍然是可以接受的。当然,我可以通过 Bash 脚本来包装表达式,该脚本逐行读取配置文件。

gle*_*man 10

parse_dhcp.awk作为

#!/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()}
Run Code Online (Sandbox Code Playgroud)

然后

awk -f parse_dhcp.awk dhcp.conf
Run Code Online (Sandbox Code Playgroud)

更模糊的是,该文件是有效的 Tcl 语法,因此我们只需要编写 DSL 以便我们可以将文件作为 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
Run Code Online (Sandbox Code Playgroud)

#!/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
Run Code Online (Sandbox Code Playgroud)


cho*_*oba 5

以下 Perl 单行似乎几乎输出了您想要的内容:

perl -ane 'print $F[-1] =~ s/[";]//gr unless /[{}]/; print /^$/ ? "\n" : " "'
Run Code Online (Sandbox Code Playgroud)

但我担心输入可能包含您想完全跳过的部分,因此需要进行更多调整:

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

意思是

  • 如果我们在包含host和的行之间},我们处理输入,否则我们跳过它。
  • 如果当前行不包含卷曲,我们打印最后一个单词,并从中删除分号和双引号
  • 如果该行包含一个结束大括号,我们打印一个换行符,否则打印一个空格。