2015-05-04 39 views
1

我有一個文件,我需要在字符串模式匹配後刪除一段文本。從文件python3.4如何刪除模式字符串匹配後的一段文本

文本:

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"; 
}; 
zone "domain2.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/domain2.com.external.signed"; 
}; 

如何搜索域2,然後刪除該行加上未來7行下面呢? 會有很多域。

+0

請檢查https://regex101.com/r/wU4xF3/2。我認爲你需要將行與「domain2」匹配,直到以可選空白+}開始的行;或者字符串的結尾。 –

回答

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")來覆蓋原文。

0

如果你知道它永遠是7行下面的正則表達式選擇其中:

[^\n]*domain2([^\n]*\n){7} 

我不知道該怎麼做,在Python,但我認爲這將是容易的,如果你要弄清楚知道python。

+0

我正試圖避免一個系統()命令 – mine

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) 
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) 
相關問題