regex - Replace block of code surrounded by nested curly braces -


i have block of setting:

...     server {         listen       80 default_server;         listen       [::]:80 default_server;         server_name  _;         root         /usr/share/nginx/html;          # load configuration files default server block.         include /etc/nginx/default.d/*.conf;          location / {         }          error_page 404 /404.html;             location = /40x.html {         }          error_page 500 502 503 504 /50x.html;             location = /50x.html {         }     } } 

i want replace whole server block block. looking use awk or sed. replaced with

...     server {         listen              80;         listen              443 ssl;         server_name         www.example.com;         ssl_certificate     www.example.com.crt;         ssl_certificate_key www.example.com.key;     } } 

regex pattern found working on selecting needed. using -m (multiline) modifier. tool used: regex101.com

server {(?:[^}]*}[^}])* or server {[\s\s]*(?=^\s{4}\}$)\s*}

this may want:

$ cat tst.awk bracecnt {     if ( /{/ ) { bracecnt++ }     if ( /}/ ) { bracecnt-- } } !bracecnt /^[[:space:]]*server[[:space:]]*{/ {     print newblock     bracecnt = 1 }  $ awk -v newblock='        listen              80;         listen              443 ssl;         server_name         www.example.com;         ssl_certificate     www.example.com.crt;         ssl_certificate_key www.example.com.key;' -f tst.awk file ...     server {         listen              80;         listen              443 ssl;         server_name         www.example.com;         ssl_certificate     www.example.com.crt;         ssl_certificate_key www.example.com.key;     } } 

or if prefer relying on indentation/white space counting braces, work too:

$ cat tst.awk inblock && /^ {4}}/ { inblock=0 } !inblock /^[[:space:]]*server[[:space:]]*{/ { print newblock; inblock=1 } 

or if want number of spaces before closing brace match number before server rather hard-coding 4:

$ cat tst.awk inblock && ($0 ~ "^[[:space:]]{"indent"}}") { inblock=0 } !inblock /^[[:space:]]*server[[:space:]]*{/ {     indent = index($0,"s") - 1     print newblock; inblock=1 } 

etc., etc.... depends on requirements....


Comments