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をキャッチする必要がある場合があります)、MAC アドレスを削除するかどうかを簡単にテストできます。AttributeErrorMAC アドレスが一致しない場合は、リース全体を出力ファイルに書き戻し、startとのstop位置を使用してそのリースの元のテキストを取得します (解析された情報からリースをフォーマットするよりもはるかに簡単です)。

于 2012-11-29T11:02:51.440 に答える