Matrix
Matrix

Reputation: 2649

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.

Upvotes: 0

Views: 120

Answers (2)

Sangbok  Lee
Sangbok Lee

Reputation: 2228

Entire regex version.

import re
def remove(text):
  with open('nginx.conf', 'r') as f:
    word = f.read()
    if re.search(text, word):
      rx = re.compile('server \{.*server_name\s*' + text + '.*?^}', re.DOTALL | re.MULTILINE)
      word = re.sub(rx, '', word)
      with open('nginx.conf', 'w') as f:
        f.write(word)

remove("dev-example")

Basically, it searches server { ... server_name ... dev-example ... \n}. So the entire block will be replaced. ^ means the beginning of each line in MULTILINE mode so it bypasses the internal } which is indented.

Upvotes: 1

ant0nisk
ant0nisk

Reputation: 591

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.

Upvotes: 1

Related Questions