2015-05-04 2 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"; 
}; 

Как искать domain2, затем удалите эту строку плюс следующие 7 строк ниже его? Будет много доменов.

+0

Пожалуйста, проверьте https://regex101.com/r/wU4xF3/2. Я думаю, вам нужно совместить строку с «domain2» и до строки, которая начинается с необязательного пробела + '};' или конца строки. –

ответ

2

Вы можете написать в NamedTemporaryFile, пропуская 7 строк каждый раз, когда "domain2.com" находится в соответствии с itertool.islice, используя 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 означает, что файл не будет удален, если процесс прерван, ничто не будет записано в t он оригинал, наконец, мы используем move(temp.name,"test.txt") для перезаписи оригинала.

0

Если вы знаете, что всегда будет 7 линия следующее регулярное выражение выбирает их:

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

Я не знаю, как сделать это в Python, но я думаю, что это будет легко понять, если вы знать питон.

+0

Я пытался избежать команды system() – 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  

Затем скопируйте файл temp на свой оригинал.

Если ваш файл имеет абсолютный рисунок из 7 строк после цели - лучше всего подходит solution Padraic Cunningham. Если у вас есть переменные строковые блоки или что-то лучше описывается с помощью регулярного выражения, этот подход удобен.


За то, что вы работаете, попробуйте:

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)