sed заменить текст, содержащий новую строку

У меня есть скрипт bash для установки веб-сервера на моем сервере Ubuntu.

Я хотел бы в /etc/apache2/apache2.conf заменить

#ServerRoot "/etc/apache2"

#

by

#ServerRoot "/etc/apache2"
ServerName localhost

#

Если я выполняю

sed -i 's|#ServerRoot "/etc/apache2"|#ServerRoot "/etc/apache2"\nServerName localhost|' /etc/apache2/apache2.conf

, он работает, но я хотел бы включить пустую строку и # после #ServerRoot, чтобы избежать добавления дважды имя_сервера, если сценарий выполняется дважды.

Я попробовал

sed -i 's|#ServerRoot "/etc/apache2"\n\n#|#ServerRoot "/etc/apache2"\nServerName localhost\n\n#|' /etc/apache2/apache2.conf

Но он не работает.

1
задан 3 July 2014 в 15:06

2 ответа

Наконец, с помощью этой помощи получен двойной контроль \n, работающий в sed. Немного глотка:

sed -Ei ':a;N;$!ba;s/^(#ServerRoot[^\n]*)\n\n/\1\nServerName localhost\n\n/' apache2.conf

И awk, который делает то же самое (дольше, но легче понять IMO). Логика и sponge объясняются в последнем разделе.

awk '{print}/^#ServerRoot/{getline; if($0=="") print "ServerName localhost"; print}' apache2.conf | sponge apache2.conf

Редактировать: sed не так сложно, как я думал изначально. Вы просто хотите сопоставить и добавить (команда a); вам не нужно заменять. Я тестировал следующие действия:

sed -i '/^#ServerRoot/a ServerName localhost' apache2.conf

Вы можете быть более конкретным в своем матче, если хотите, и я оставлю awk ниже ради потомства.

[d6 ]

Редактирование довольно тривиально с awk, но для того, чтобы записать обратно в тот же файл, нам нужен либо временный файл-посредник, либо sponge (из пакета moreutils). Я покажу оба метода.

awk '{print}/^#ServerRoot/{print "ServerName localhost"}' apache2.conf > tmp
mv tmp apache2.conf

Или

awk '{print}/^#ServerRoot/{print "ServerName localhost"}' apache2.conf | sponge apache2.conf

awk просто печатает каждую найденную строку, но в случае соответствия для ^#ServerName затем записывает вашу строку ServerName. Я считаю, что этот вид обработки намного проще читать, чем произвольная «замена» с помощью sed.

0
ответ дан 24 May 2018 в 06:02
  • 1
    Хорошо, но проблема не в том, что если вы дважды выполняете сценарий, строка ServerName будет добавлена ​​дважды. – tweetysat 3 July 2014 в 14:49
  • 2
    @tweetysat добавить проверку grep. Еще лучше используйте папку conf-available и создайте файл. – muru 3 July 2014 в 14:51
  • 3
    @muru Я попробовал ваше решение, создав файл в conf-доступном. Он работает нормально. Благодарю. – tweetysat 3 July 2014 в 16:09

Другой способ (спасибо muru), но немного вне контекста, потому что не использовал sed:

Для Ubuntu 14.04:

Создайте файл Ubuntu 14.04 dans / etc / apache2 / conf-available / содержащий

ServerName localhost

Создайте символическую ссылку в / etc / apache2 / conf-enabled /

sudo ln -s /etc/apache2/conf-available/fqdn.conf /etc/apache2/conf-enabled/fqdn.conf
0
ответ дан 24 May 2018 в 06:02

Другие вопросы по тегам:

Похожие вопросы: