2012-08-22 31 views
0

我試圖刪除apache配置文件中的一段文本,特別是虛擬主機。我需要刪除虛擬主機容器,包括< VirtualHost>標記。
使用python刪除文件中的一段文字

Stuff 

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

stuff 

到目前爲止,我試圖將其正規化。但它不會更改文件。我實際上試圖更新文件並刪除代碼。

這是我迄今爲止沒有工作。除非指定re.DOTALL

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

令牌評論(有人必須說:) - python提供了一堆標記解析器,它們更適合於p解析html/xml。嘗試使用正則表達式解析標記通常不可取。 – mgilson

+0

從我所看到的,這不是標記,它看起來像一個Apache配置文件。它們使用類似的語法,但它不是有效的標記,例如,當使用' javex

回答

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

+0

這個答案涵蓋了這兩個問題,非常好。關於'with'陳述的好消息! – javex

2

圓點字符.將不匹配換行符:

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

(見蟒蛇re文檔)

+0

我仍然不認爲這將工作,因爲用戶逐行解析文件(我認爲) - '在fileinput.input(...)線' – mgilson

相關問題