如果要在較大的文件上使用正則表達式,請使用mmap。
import mmap
import re
from tempfile import NamedTemporaryFile
with open(ur_fn, 'r+') as tgt, NamedTemporaryFile(dir='/tmp', delete=False) as out:
mm=mmap.mmap(tgt.fileno(), 0)
fn=out.name
pat=re.compile(r'^(\s*zone "domain.*?)(?=^\s*zone|\Z)', flags=re.S | re.M)
for i, block, span in ((n, m.group(1), m.span()) for n,m in enumerate(pat.finditer(mm))):
if "domain2.com" in block:
continue
else:
out.write(block)
with open(fn) as inf:
print(inf.read()) # replace this with copying the file onto orig, etc
然後將臨時文件複製到原始文件中。
如果您的文件具有目標後7行的絕對模式 - Padraic Cunningham的solution更好。如果你有可變的行塊,或者用正則表達式更好地描述,這種方法很方便。
爲你工作,請嘗試:
import mmap
import re
from tempfile import NamedTemporaryFile
name="new_domain2.com"
template='''\
zone "%s" {
type slave;
masters {108.61.190.64;};
allow-notify{108.61.190.64;};
allow-transfer {trusted;};
key-directory "/usr/local/etc/namedb/";
file "/usr/local/etc/namedb/nyctelecomm.com.external.signed";
};
'''
with open('/tmp/dms.txt', 'r+') as tgt, NamedTemporaryFile(dir='/tmp', delete=False) as out:
mm=mmap.mmap(tgt.fileno(), 0)
fn=out.name
pat=re.compile(r'^(\s*zone "domain.*?)(?=^\s*zone|\Z)', flags=re.S | re.M)
for i, block, span in ((n, m.group(1), m.span()) for n,m in enumerate(pat.finditer(mm))):
if re.match(r'zone "domain2\.com', block):
out.write(template % name)
else:
out.write(block)
請檢查https://regex101.com/r/wU4xF3/2。我認爲你需要將行與「domain2」匹配,直到以可選空白+}開始的行;或者字符串的結尾。 –