extrai blocos de servidores de Nginx conf

2

Eu tenho o seguinte arquivo conf para o 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 é um exemplo de foo que encontrei em www.nginx.com.

O objetivo é extrair todos os blocos dos servidores para vários tratamentos. Neste caso particular, existem dois blocos de servidores em que estou interessado.

Como trabalho em ambientes muito limitados, só posso usar os comandos dos sistemas sed / grep / awk / unix. Não python, sem pérola, ...

O problema com esse tipo de arquivos de configuração é que talvez seja possível que o próprio bloco server contenha alguns sub-blocos (ou seja, server { ... directive { ... }} ). Considerando isso, é impossível simplesmente usar grep -oP "server {.*?}" .

Pode grep fazer o trabalho? Eu tentei muitos regex diferente, mas não encontrei o bom. Por enquanto, eu trabalhei com o arquivo acima sem barra invertida (por exemplo, cat $FILE | tr -d "\n" ). Eu tentei coisas como grep -oP "server\s{1,}{.*?({.*?}){0,}}" , mas isso não se ajusta às minhas necessidades ...

A razão que eu quero usar grep é que eu acho que awk não é muito legível depois, e manter o código deve ser mais fácil com grep - mas eu poderia abrir uma exceção se for mais fácil com awk !

Obrigado :)

EDITAR:

A saída deve se parecer com:

"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 eu posso tratar usando comandos como echo $OUTPUT | tr -d ... | grep -v ... . Se possível, eu quero ter cada bloco de servidor extraído em uma única linha para fazer um loop no resultado!

    
por Colin Leverger 01.07.2016 / 16:27

1 resposta

2

Se eu entendi corretamente, você está procurando 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;
    }
  }

Explicação

  • /server *{/{c=1; print; next;} : se essa linha corresponder a server , 0 ou mais espaços e, em seguida, { , defina a variável c como 1. Portanto, c será 1 sempre que encontrarmos um novo bloco server{ . Então print da linha e pule para o next one.
  • c&&/{/{c++} : se o c for definido e não 0, e essa linha corresponder a { , incremento c por 1 ( c++ ). Isso poderia ter sido escrito como if(c && /{/){ c=c+1} . Assim, o valor de c aumentará para cada bloco { aninhado encontrado.

  • c&&/}/{c--} : se c for definido e não 0, e essa linha corresponder a } , decremento c por 1. Isso pode ter sido escrito como if(c && /}/){c=c-1} . Isso garante que o valor de c desça à medida que cada bloco {} aninhado é fechado.

  • c : este é um truque de awk . A ação padrão quando algo é avaliado como true em awk é imprimir a linha atual. Aqui, ele será impresso se c for definido e não 0 (verdadeiro). Por causa dos comandos acima dos quais incremento e decremento c dependendo se estamos em um bloco server , isso resultará na impressão somente das linhas que você está procurando.

por 01.07.2016 / 16:43