使用python删除文件中的文本块

时间:2012-08-22 13:12:57

标签: python

我正在尝试删除apache配置文件中的文本块,特别是虚拟主机。我需要删除虚拟主机容器,包括<虚拟主机>标记。

Stuff

<VirtualHost   asdfalsdkf:*> 
asldkfjasl;dkfjasldkfj
asdfljasldjf;laksdfj
a;lsdkfj;laksjdfas
asldkfjasldfkj
3495034ijfgdl9)_*)(%$
more stuff
</VirtualHost>

stuff

到目前为止,我已尝试将其重新出发。但它没有改变文件。我实际上是在尝试更新文件并删除代码。

到目前为止,这是我无法正常工作的。

for line in fileinput.input('/etc/apache2/apache2.conf.replace',inplace=True):
    sys.stdout.write(re.sub(r'<VirtualHost.*?>.*?</VirtualHost>','',line))

2 个答案:

答案 0 :(得分:3)

这里有两个问题。第一个是(正如javex指出的那样)你需要使用re.DOTALL

但这还不够。你仍然只是一次给正则表达式一行,所以它永远不会看到开始和结束VirtualHost标签。 AFAIK,没有办法使用fileinput获取文件的全部内容,但假设您不需要接受来自STDIN的输入,并且文件将足够小以便一次读入内存(应该是对于Apache配置文件的情况),这应该这样做:

import os
import sys
import re

for fn in sys.argv[1:]:
    os.rename(fn, fn + '.orig')
    with open(fn + '.orig', 'rb') as fin, open(fn, 'wb') as fout:
        data = fin.read()
        data = re.sub(r'<VirtualHost.*?>.*?</VirtualHost>', '', data,
                      flags=re.DOTALL)
        fout.write(data)

这需要Python 2.7,因为我在with语句中使用了嵌套上下文的内置语法,但是使用contextlib.nested可以获得与早期版本相同的功能

答案 1 :(得分:2)

除非指定.,否则点字符re.DOTALL将与新行不匹配:

for line in fileinput.input('/etc/apache2/apache2.conf.replace',inplace=True):
    sys.stdout.write(re.sub(r'<VirtualHost.*?>.*?</VirtualHost>','',line, flags=re.DOTALL))

(参见pythons re文档)