我有一个文件,我需要在字符串模式匹配后删除一段文字。
文件中的文字:
ContentControl
如何搜索domain2,然后删除该行以及下面的7行? 会有很多域名。
答案 0 :(得分:2)
您可以写NamedTemporaryFile,每次"domain2.com"
与itertool.islice一致时跳过7行,使用shutil.move替换最后的原始文件:
from tempfile import NamedTemporaryFile
from itertools import islice
from shutil import move
with open("test.txt") as f, NamedTemporaryFile("w",dir=".", delete=False) as temp:
for line in f:
if '"domain2.com"' in line:
list(islice(f, 7))
else:
temp.write(line)
move(temp.name,"test.txt")
输出:
zone "domain1.com" {
type slave;
masters {10.10.10.1;};
allow-notify{10.10.10.1;};
allow-transfer {trusted;};
key-directory "/usr/local/etc/namedb/";
file "/usr/local/etc/namedb/domain1.com.external.signed";
};
delete=False
表示文件不会被删除,如果进程中断,则不会将任何内容写入原文,最后我们使用move(temp.name,"test.txt")
覆盖原文。
答案 1 :(得分:0)
如果您知道它总是7行,则以下正则表达式选择它们:
[^\n]*domain2([^\n]*\n){7}
我不知道如何在python中这样做,但我认为如果你知道python会很容易理解。
答案 2 :(得分:0)
import re
p = re.compile(ur'zone.*?\bdomain2\b.*?{[\s\S]*?\n};')
test_str = u"zone \"domain1.com\" {\n type slave;\n masters {10.10.10.1;};\n allow-notify{10.10.10.1;};\n allow-transfer {trusted;};\n key-directory \"/usr/local/etc/namedb/\";\n file \"/usr/local/etc/namedb/domain1.com.external.signed\";\n};\nzone \"domain2.com\" {\n type slave;\n masters {10.10.10.1;};\n allow-notify{10.10.10.1;};\n allow-transfer {trusted;};\n key-directory \"/usr/local/etc/namedb/\";\n file \"/usr/local/etc/namedb/domain2.com.external.signed\";\n};"
subst = u""
result = re.sub(p, subst, test_str)
答案 3 :(得分:0)
如果要在较大的文件上使用正则表达式,请使用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)