删除使用python从dhcpd.leases获取mac的租约?

时间:2012-11-29 10:23:48

标签: python regex parsing

我正在尝试使用python根据其mac地址从dhcpd.lease中删除租约。

这是一个dhcpd.lease示例

lease 10.14.53.253 {
  starts 3 2012/10/17 09:27:20;
  ends 4 2012/10/18 09:27:20;
  tstp 4 2012/10/18 09:27:20;
  binding state free;
  hardware ethernet 00:23:18:62:31:5b;
} 
lease 10.14.53.252 {
  starts 3 2012/10/17 10:15:17;
  ends 4 2012/10/18 10:15:17;
  tstp 4 2012/10/18 10:15:17;
  binding state free;
  hardware ethernet 70:71:bc:c8:46:3c;
  uid "\001pq\274\310F<";
}

假设我得到'00:23:18:62:31:5b'。然后我应该删除属于这个租约的所有行。删除后,文件应该看起来像

lease 10.14.53.252 {
  starts 3 2012/10/17 10:15:17;
  ends 4 2012/10/18 10:15:17;
  tstp 4 2012/10/18 10:15:17;
  binding state free;
  hardware ethernet 70:71:bc:c8:46:3c;
  uid "\001pq\274\310F<";
}

我很简单地读取一个文件并把它写成一个字符串,但我不知道在那之后该怎么做。我尝试了这个正则表达式但没有奏效。它只检查了文件的第一行。

fh = open(DHCPFILE)
lines = fh.read()
fh.close()
m = re.match(r"(.*lease.*%s.*})" % mac ,lines)

1 个答案:

答案 0 :(得分:1)

这个问题形如正则表达钉,所以请放下锤子。

正确的工具是将内容解析为python结构,过滤掉你不想要的项目,然后再写出剩下的条目。

pyparsing会使解析工作变得简单;以下内容基于an existing example

from pyparsing import *

LBRACE,RBRACE,SEMI,QUOTE = map(Suppress,'{};"')
ipAddress = Combine(Word(nums) + ('.' + Word(nums))*3)
hexint = Word(hexnums,exact=2)
macAddress = Combine(hexint + (':'+hexint)*5)
hdwType = Word(alphanums)

yyyymmdd = Combine((Word(nums,exact=4)|Word(nums,exact=2))+
                    ('/'+Word(nums,exact=2))*2)
hhmmss = Combine(Word(nums,exact=2)+(':'+Word(nums,exact=2))*2)
dateRef = oneOf(list("0123456"))("weekday") + yyyymmdd("date") + \
                                                        hhmmss("time")

startsStmt = "starts" + dateRef + SEMI
endsStmt = "ends" + (dateRef | "never") + SEMI
tstpStmt = "tstp" + dateRef + SEMI
tsfpStmt = "tsfp" + dateRef + SEMI
hdwStmt = "hardware" + hdwType("type") + macAddress("mac") + SEMI
uidStmt = "uid" + QuotedString('"')("uid") + SEMI
bindingStmt = "binding" + Word(alphanums) + Word(alphanums) + SEMI

leaseStatement = startsStmt | endsStmt | tstpStmt | tsfpStmt | hdwStmt | \
                                                        uidStmt | bindingStmt
leaseDef = "lease" + ipAddress("ipaddress") + LBRACE + \
                            Dict(ZeroOrMore(Group(leaseStatement))) + RBRACE

input = open(DHCPLEASEFILE).read()
with open(OUTPUTFILE, 'w') as output:
    for lease, start, stop in leaseDef.scanString(input):
        if lease.hardware.mac != mac:
            output.write(input[start:stop])

上面的代码简洁地定义了dhcp.leases文件的语法,然后使用scanString()来解析文件中的每个租约。 scanString()返回一系列匹配,每个匹配包含一个解析结果以及原始字符串中的起始位置和结束位置。

解析结果具有.hardware.mac属性(如果输入中没有硬件语句,您可能希望捕获AttributeError例外情况,从而可以轻松测试您的MAC地址去除。如果MAC地址不匹配,我们将整个租约写回输出文件,使用startstop位置获取该租约的原始文本(比格式化租约更容易)解析的信息)。