使用Bash解析dhcpd.lease文件

时间:2010-01-26 21:35:37

标签: bash parsing grep

我尝试用Basel解析我的dhcpd.lease文件。典型条目如下所示:

lease 192.168.20.4 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 00:00:00:00:00:00;
    uid 00:00:00:00:00:00;
    client-hostname "examle-workstation1";
}

我得到的所有信息都是MAC,我想要的是IP和客户端主机名。但也许,没有客户端主机名。条目如下所示:

lease 192.168.20.5 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 00:00:00:00:00:00;
}

我的第一个想法是grep lease属性,硬件ethernet属性和uid属性,并将它们全部放在一行上。然后解析它。

但我的问题是,我有一个大文件,在许多文件中分配了许多条目。树看起来像这样:

dhcpd-leases
-- 192.168.20.0
-- 192.168.30.0
-- 192.168.40.0
[...]

我所得到的就是从其他文件解析到列表的MAC。所以我从这个列表开始,想要用我的MAC grep the Attributes ip,mac:

for ENTRY in $MACLIST
do
    VAR$(cat "dhcpd-leases/10.148.$NETWORK.2/dhcpd.leases" | grep -E "$MAC|lease|client-hostname")
    echo $VAR
done

但是因为$ VAR中的许多内容以及我无法将其解析出来的文件。

有人可以帮忙吗?

祝你好运 彼得

5 个答案:

答案 0 :(得分:2)

假设你的maclist文件看起来像这样(例如只有一个条目)

$ cat maclist
00:00:00:00:00:01

和您的租借文件一样

$ cat file
lease 192.168.20.4 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 00:00:00:00:00:00;
    uid 00:00:00:00:00:00;
    client-hostname "examle-workstation1";
}

lease 192.168.20.5 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 00:00:00:00:00:00;
}

lease 192.168.20.6 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 00:00:00:00:00:01;
    uid 00:00:00:00:00:01;
    client-hostname "examle-workstation2";
}


lease 192.168.20.7 {
    starts 6 2009/06/27 00:40:00;
    ends 6 2009/06/27 12:40:00;
    hardware ethernet 01:00:00:00:00:00;
}

你可以试试这个

awk 'BEGIN{
    while( (getline line < "maclist") > 0){
        mac[line]
    }
    RS="}"
    FS="\n"
}
/lease/{
    for(i=1;i<=NF;i++){
        gsub(";","",$i)
        if ($i ~ /lease/) {
            m=split($i, IP," ")
            ip=IP[2]
        }
        if( $i ~ /hardware/ ){
            m=split($i, hw," ")
            ether=hw[3]
        }
        if ( $i ~ /client-hostname/){
            m=split($i,ch, " ")
            hostname=ch[2]
        }
        if ( $i ~ /uid/){
            m=split($i,ui, " ")
            uid=ui[2]
        }
    }
    if ( ether in mac ){
        print "ip: "ip " hostname: "hostname " ether: "ether " uid: "uid
    }
} ' file

输出

$ ./shell.sh
hostname: "examle-workstation2" ether: 00:00:00:00:00:01 uid: 00:00:00:00:00:01

答案 1 :(得分:1)

如果您尝试获取MAC和IP,最好使用arp -s命令而不是查看DHCP租约文件。

答案 2 :(得分:1)

我喜欢awk,但是当程序变大时我不喜欢它。

所以我找到了解析leases文件的另一种方法,首先找到一个unix命令链,将文件转换为两列格式,第一列是ip地址,第二列是mac地址:

cat dhcpd.leases |  egrep -o 'lease.*{|ethernet.*;' | awk '{print $2}' | xargs -n 2 | cut -d ';' -f 1

使用简单的awk命令,然后您可以从mac地址获取IP地址。以下是作为shell函数构建的完整命令:

function f_mac_to_ip {

parseResult=$(cat /var/lib/dhcp/db/dhcpd.leases |  egrep -o 'lease.*{|ethernet.*;' | awk '{print $2}' | xargs -n 2 | cut -d ';' -f 1  | grep $1 | awk '{print $1}')
    echo "$parseResult"
}

我对租约格式不太了解。如果有没有“ethernet”字段的条目,则上述解析将不起作用。

答案 3 :(得分:0)

Text::DHCPLeases也可以完全满足您的需求,而无需重新发明轮子。 :)

答案 4 :(得分:0)

不一定比@ ghostdog74更好,但这是一个转换为json的脚本:

#!/usr/bin/awk -f

# Start with array creation
BEGIN {
    printf "[";
}

# New lease: start object 
/^lease/ {
    # If that ip is unknown, create a new JSON object
    if (!known[$2]) {
        # if this object is not the first, print a comma
        if (!notFirst) {
            notFirst=1;
        } else {
            printf ",";
        }

        # create a new JSON object with the first key being the IP (column 2)
        printf "{\"ip\":\"%s\"", $2; known[$2]=1;

        # print subsequent lines, see below
        p=1;
    }
}

# If printing is enabled print line as a JSON key/value pair
p && /^  / {
    # Print key (first word)
    printf ",\"%s\":", $1;

    # Clean up the rest of the line: trim whitespace and trailing ;, remove " and escape \
    $1="";
    gsub(/\\/, "\\\\", $0);
    gsub(/"/, "", $0);
    gsub(/^[\t ]*/, "", $0);
    gsub(/;$/, "", $0);
    printf "\"%s\"", $0;
}

# End of lease: close JSON object and disable printing
/^\}$/ {
    if (p) {
        printf "}"
    }
    p=0
}

# Close the JSON array
END {
    print "]";
}

结果:

$ /opt/dhcpd.leases_to_json.awk /var/lib/dhcp/dhcpd.leases | jq .
[
  {
    "ip": "10.7.37.10",
    "starts": "3 2019/08/28 22:24:26",
    "ends": "3 2019/08/28 22:34:26",
    "cltt": "3 2019/08/28 22:25:32",
    "binding": "state active",
    "next": "binding state free",
    "rewind": "binding state free",
    "hardware": "ethernet xx:xx:xx:xx:xx:xx",
    "client-hostname": "zzzzzzz"
  },
  {
    "ip": "10.7.37.11",
    "starts": "3 2019/08/28 22:26:10",
    "ends": "3 2019/08/28 22:36:10",
    "cltt": "3 2019/08/28 22:26:10",
    "binding": "state active",
    "next": "binding state free",
    "rewind": "binding state free",
    "hardware": "ethernet xx:xx:xx:xx:xx:xx",
    "uid": "\\001pv\\377\\001\\005~",
    "client-hostname": "xxxx"
  }
]