Раскомментируйте закрывающую награду через sed - PullRequest
0 голосов
/ 10 мая 2018

Я хочу использовать sed, чтобы раскомментировать и изменить несколько строк в моей конфигурации ngnix

Это ..

...
# location ~ \.php$ {
#   include snippets/fastcgi-php.conf;
#   # With php-cgi (or other tcp sockets):
#   fastcgi_pass 127.0.0.1:9000;
#   # With php-fpm (or other unix sockets):
#   fastcgi_pass unix:/run/php/php7.0-fpm.sock;
# }
...

.. должно стать таким:

...
location ~ \.php$ {
    include snippets/fastcgi-php.conf;
#   # With php-cgi (or other tcp sockets):
#   fastcgi_pass 127.0.0.1:9000;
#   # With php-fpm (or other unix sockets):
    fastcgi_pass unix:/run/php/php7.1-fpm.sock;
}
...

Вот что я использовал, чтобы раскомментировать первые три строки:

sudo sed -i 's/#\s*location ~ \\\.php$ {/location ~ \\.php$ {/g' /etc/nginx/sites-available/default
sudo sed -i 's/#\s*include snippets\/fastcgi-php\.conf;/\tinclude snippets\/fastcgi-php.conf;/g' /etc/nginx/sites-available/default
sudo sed -i 's/#\s*fastcgi_pass unix:\/run\/php\/php7\.0-fpm\.sock;/\tfastcgi_pass unix:\/run\/php\/php7\.1-fpm.sock;/g' /etc/nginx/sites-available/default

Мне удалось заставить эти строки работать, но я не уверен, как раскомментировать заключительную награду, не раскомментировав и другие в остальной части файла. Есть мысли о том, как к этому подойти?

Решение

Благодаря ответу Винтермута мне удалось заставить все работать. Вот мое окончательное решение, все в одной командной строке:

sudo sed -i '/^\s*#\s*location ~ \\\.php\$ {/ {
    :loop /\n\s*#\s*}/! {
        N;
        b loop;
    };
    s@#@@;
    s@#\(\s*include snippets/fastcgi-php\.conf;\)@\1@;
    s@#\(\s*fastcgi_pass unix:/run/php/php7\.\)[0-9]\+\(-fpm\.sock;\)@\11\2@;
    s@\n\(\s*\)#\(\s*}\)@\n\1\2@;
};' /etc/nginx/sites-available/default

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Вот альтернативное gnu-awk решение с пользовательским RS:

awk -v RS='# location [^{]*{[^}]*}\n' 'RT {
   RT = gensub(/(^|\n)[[:blank:]]*#([[:blank:]]*(location|include|fastcgi_pass unix|}))/, "\\1\\2", "g", RT)
   RT = gensub(/(php7\.)0/, "\\11", "1", RT)
}
{ORS=RT} 1' file

...
 location ~ \.php$ {
   include snippets/fastcgi-php.conf;
#   # With php-cgi (or other tcp sockets):
#   fastcgi_pass 127.0.0.1:9000;
#   # With php-fpm (or other unix sockets):
   fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
 }
...

Ссылка:

0 голосов
/ 10 мая 2018

Поскольку файл конфигурации, вероятно, содержит гораздо больше, чем этот раздел, ложные совпадения - это проблема, которую следует рассмотреть здесь. В частности, соответствие ^#\s*} и надежда на лучшее может привести к раскомментированию совершенно не связанных строк где-то еще в файле.

Из-за этого я собираю все строки, которые принадлежат данному разделу, прежде чем раскомментировать. Я думаю в соответствии с этим: поставить код

/^#\s*location ~ \\\.php\$ {/ {
  :loop
  /\n#\s*}/! {
    N
    b loop
  }
  s/^#//
  s@#\(\s*include snippets/fastcgi-php\.conf;\)@\1@
  s@#\(\s*fastcgi_pass unix:/var/run/php/php7\.\)0\(-fpm\.sock;\)@\11\2@
  s/\n#\(\s*}\)/\n\1/
}

в файл, скажем uncomment.sed, затем запустите

sed -f uncomment.sed /etc/nginx/sites-available/default

Если результат вас устраивает, добавьте параметр -i для редактирования на месте.

Этот код работает следующим образом:

/^#\s*location ~ \\\.php\$ {/ {    # starting with the first line of the section
                                   # (regex taken from the question):
  :loop                            # jump label for looping
  /\n#\s*}/! {                     # Until the last line is in the pattern space
    N                              # fetch the next line from input, append it
    b loop                         # then loop
  }

  # At this point, we have the whole section in the pattern space.
  # Time to remove the comments.

  # There's a # at the beginning of the pattern space; remove it. This
  # uncomments the first line.
  s/^#//

  # The middle two are taken from the question, except I'm using @ as 
  # a separator so I don't have to escape all those slashes and captures
  # to avoid repeating myself.
  s@#\(\s*include snippets/fastcgi-php\.conf;\)@\1@
  s@#\(\s*fastcgi_pass unix:/var/run/php/php7\.\)0\(-fpm\.sock;\)@\11\2@

  # Uncomment the last line. Note that we can't use ^ here because that
  # refers to the start of the pattern space. However, because of the
  # looping construct above, we know there's only one # directly after
  # a newline followed by \s*} in it, and that's the comment sign before
  # the last line. So remove that, and we're done.
  s/\n#\(\s*}\)/\n\1/
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...