Sarah Sarah - 9 months ago 29
Python Question

Remove specific multiple lines from a file using python

I want to look for specific text("dev-example") in my Nginx-config file and remove the related server block for that by using a python script(python 2.7).

Part of my file looks like below:

server {
listen 80;
server_name dev-example.com;
location / {
proxy_pass http://dev-example.io:5015/;
proxy_redirect off;

##proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

client_max_body_size 10m;
client_body_buffer_size 128k;

proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;

proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
}

server {
listen 80;
server_name test.example.com;
location / {
proxy_pass http://test.example.io:5016/;
proxy_redirect off;

##proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

client_max_body_size 10m;
client_body_buffer_size 128k;

proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;

proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
}


The output should be as follows:

server {
listen 80;
server_name test.example.com;
location / {
proxy_pass http://test.example.io:5016/;
proxy_redirect off;

##proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

client_max_body_size 10m;
client_body_buffer_size 128k;

proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;

proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
}


I don't want to create new file for output, I just want to remove those lines from the existent file. As far as I found I can use regular expression like:

def remove(text)
with open('nginx.conf') as f:
for word in f:
word = word.strip()
if re.search(text,word):
rx = re.compile("""server.*?{.*?server_name\s*text.*?}""", re.VERBOSE)
re.sub(rx, '', ...)

remove("dev-example")


However I don't know how to remove them. I'm not sure what I can put in the third art of re.sub() besides, the pattern doesn't work file when there is internal '}'. Any help would be appreciated.

Answer Source

Ok, this approach is very simple. It doesn't use Regex but it can work in your case.

def remove_block_from_file(filename, search_text):
    output = ""
    with open(filename,'r') as f:
        output = f.read()

    blocks = [i for i in output.split("server {") if i != ""] # Removes the empty entries in the `block` list.

    output = ""
    for b in blocks:
        if search_text not in b: # If the text isn't found in that block, append it to the new output.
            output += "server {" + b + "\n"


    with open(filename, 'w') as f:
        f.write(output)

So in your case call it like this:

remove_block_from_file("nginx.conf", "dev-example")

This searches for any text in that block, since that is what you ask in your question and not specifically for the server name.

I hope this helps.