extraer bloques de serveres de Nginx conf

Tengo el siguiente file conf para nginx:

user www www; ## Default: nobody ... events { worker_connections 4096; ## Default: 1024 } http { include conf/mime.types; ... server { # php/fastcgi listen 80; server_name domain1.com www.domain1.com; access_log logs/domain1.access.log main; root html; location ~ \.php$ { fastcgi_pass 127.0.0.1:1025; } } server { # simple reverse-proxy listen 80; server_name domain2.com www.domain2.com; access_log logs/domain2.access.log main; # serve static files location ~ ^/(images|javascript|js|css|flash|media|static)/ { root /var/www/virtual/big.server.com/htdocs; expires 30d; } # pass requests for dynamic content to rails/turbogears/zope, et al location / { proxy_pass http://127.0.0.1:8080; } } } 

Este es un foo ejemplo que encontré en www.nginx.com.

El objective es extraer todos los bloques de serveres para diversos tratamientos. En este caso particular, hay dos bloques de serveres que me interesan.

Como trabajo en entornos muy limitados, solo puedo usar los commands de los sistemas sed / grep / awk / unix. Sin python, sin perla, …

El problema con ese tipo de files de configuration es que tal vez sea posible que el bloque del server sí contenga algunos subbloques (es decir, el server { ... directive { ... }} ). Teniendo en count eso, es imposible simplemente usar grep -oP "server {.*?}" .

¿Puede grep hacer el trabajo? He intentado muchas expresiones regulares diferentes pero no encontré la buena. Por ahora, trabajé con el file anterior sin barra invertida (es decir, cat $FILE | tr -d "\n" ). He intentado cosas como grep -oP "server\s{1,}{.*?({.*?}){0,}}" pero no se ajusta a mis necesidades …

La razón por la que quiero usar grep es porque creo que awk no es muy legible después, y mantener el código debería ser más fácil con grep , pero podría hacer una exception si es mucho más fácil con awk .

Gracias 🙂

EDITAR:

La salida debería verse así:

 "server { # php/fastcgi listen 80; server_name domain1.com www.domain1.com; access_log logs/domain1.access.log main; root html; location ~ \.php$ { fastcgi_pass 127.0.0.1:1025; } }", "server { # simple reverse-proxy listen 80; server_name domain2.com www.domain2.com; access_log logs/domain2.access.log main; # serve static files location ~ ^/(images|javascript|js|css|flash|media|static)/ { root /var/www/virtual/big.server.com/htdocs; expires 30d; } # pass requests for dynamic content to rails/turbogears/zope, et al location / { proxy_pass http://127.0.0.1:8080; } }" 

Algo que puedo tratar usando commands como echo $OUTPUT | tr -d ... | grep -v ... echo $OUTPUT | tr -d ... | grep -v ... echo $OUTPUT | tr -d ... | grep -v ... Si es posible, quiero que cada bloque de server se extraiga en una sola línea para reproducir el resultado.

Si te entiendo correctamente, estás buscando algo como:

 $ awk '/server *{/{c=1; print;next} c&&/{/{c++} c&&/}/{c--} c' file server { # php/fastcgi listen 80; server_name domain1.com www.domain1.com; access_log logs/domain1.access.log main; root html; location ~ \.php$ { fastcgi_pass 127.0.0.1:1025; } } server { # simple reverse-proxy listen 80; server_name domain2.com www.domain2.com; access_log logs/domain2.access.log main; # serve static files location ~ ^/(images|javascript|js|css|flash|media|static)/ { root /var/www/virtual/big.server.com/htdocs; expires 30d; } # pass requests for dynamic content to rails/turbogears/zope, et al location / { proxy_pass http://127.0.0.1:8080; } } 

Explicación

  • /server *{/{c=1; print; next;} /server *{/{c=1; print; next;} : si esta línea coincide con el server , 0 o más espacios y luego un { , establezca la variable c en 1. Entonces, c será 1 cada vez que encontremos un nuevo server{ bloque. Luego print la línea y salte a la next .
  • c&&/{/{c++} : si c está definido y no 0, y esta línea coincide con { , incremente c por 1 ( c++ ). Esto podría haberse escrito como if(c && /{/){ c=c+1} . Por lo tanto, el valor de c boostá para cada bloque nested encontrado.

  • c&&/}/{c--} : si c está definido y no 0, y esta línea coincide con a } , disminuya c en 1. Esto podría haberse escrito como if(c && /}/){c=c-1} . Esto asegura que el valor de c disminuye a medida que se cierra cada bloque {} nested.

  • c : este es un truco awk . La acción pnetworkingeterminada cuando algo se evalúa como verdadero en awk es imprimir la línea actual. Aquí, se imprimirá si c está definido y no 0 (verdadero). Debido a los commands sobre los cuales aumentamos y decrementamos c dependiendo de si estamos en un bloque de server , esto dará como resultado la printing solo de las líneas que buscamos.