0

我正在尝试根据其mac地址使用python从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)
4

1 回答 1

1

这个问题不是正则表达式钉子的形状,所以请放下那个锤子。

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

pyparsing将使解析工作变得容易;以下基于现有示例

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位置来获取该租约的原始文本(比从解析的信息格式化租约容易得多)。

于 2012-11-29T11:02:51.440 回答