Назад | Перейти на главную страницу

Добавить строку с помощью perl / awk / sed?

Я пытаюсь внести изменения в свой файл конфигурации apache (httpd.conf). Я пытаюсь сопоставить следующую строку:

#
# DirectoryIndex: sets the file that Apache will serve if a directory

И ПРЕДВАРИТЕЛЬНО следующий текст:

#
# Allow server status reports generated by mod_status,
# with the URL of http://servername/server-status
# Change the ".example.com" to match your domain to enable.
#
<Location /server-status>
    SetHandler server-status
    Order deny,allow
    Deny from all
    Allow from localhost ip6-localhost 127.0.0.1 192.168.0.0/255.255.255.0
</Location>

Насколько я понимаю, sed не поддерживает множественные совпадения строк, awk кажется трудным для совпадений нескольких строк. Я пытаюсь заставить Perl работать с perl -0777 -pi -e, но я не могу найти регулярное выражение, которое соответствует исходному шаблону.

Я бы предпочел сделать это одним лайнером, а не сценарием, потому что я хочу, чтобы он был переносимым (т.е. копировать и вставлять по мере необходимости).

Есть ли какие-нибудь эксперты по регулярным выражениям Perl, которые могут помочь мне найти решение?

Заранее большое спасибо Брэд

РЕДАКТИРОВАТЬ

Следующие работы:

 sed -i -e ':begin;$!N;s/#\n# DirectoryIndex/#\n# Allow server status reports generated by mod_status,\n# with the URL of http:\/\/servername\/server-status\n# Change the ".example.com" to match your domain to enable.\n#\n<Location \/server-status>\n\tSetHandler server-status\n\tOrder deny,allow\n\tDeny from all\n\tAllow from localhost ip6-localhost 192\.168\.0\.0\/255\.255\.255\.0\n<\/Location>\n\n#\n\#DirectoryIndex/;tbegin;P;‌​D' /etc/httpd/conf/httpd.conf 

Но между # и DirectoryIndex нет пробела.

Однако, если я попытаюсь изменить его на:

sed -i -e ':begin;$!N;s/#\n# DirectoryIndex/#\n# Allow server status reports generated by mod_status,\n# with the URL of http:\/\/servername\/server-status\n# Change the ".example.com" to match your domain to enable.\n#\n<Location \/server-status>\n\tSetHandler server-status\n\tOrder deny,allow\n\tDeny from all\n\tAllow from localhost ip6-localhost 192\.168\.0\.0\/255\.255\.255\.0\n<\/Location>\n\n#\n\# DirectoryIndex/;tbegin;P;‌​D' /etc/httpd/conf/httpd.conf 

Команда sed зависает и никогда не завершается. Кажется, я не могу понять, почему?

Единственная разница - это пробел между # и DirectoryIndex.

Ты должен попытаться

perl -0777 -i.original -pe 's/#\n# DirectoryIndex: sets the file that Apache will serve if a directory/#\n# DirectoryIndex: sets the file that Apache will serve if a directory\n#\n# Allow server status reports generated by mod_status,\n# with the URL of http:\/\/servername\/server-status\n# Change the ".example.com" to match your domain to enable.\n#\n<Location \/server-status>\n    SetHandler server-status\n    Order deny,allow\n    Deny from all\n    Allow from localhost ip6-localhost 127.0.0.1 192.168.0.0\/255.255.255.0\n<\/Location>/igs' /etc/httpd/conf/httpd.conf

Не забудьте убежать от своей строки replace (\/ для /) когда вы используете / разделитель в инструменте регулярного выражения

Если вы запускаете его через оболочку, вы можете сделать такой сценарий

#Set serach delimiter
search='#\n# DirectoryIndex: sets the file that Apache will serve if a directory'

#Set replace string from file
replace=$search"\n"$(cat newConfFile)

#Escape "/" char
replace=${replace//\//\\\/ }

#Launch the script
perl -0777 -i.original -pe 's/${search}/${replace}/igs' /etc/httpd/conf/httpd.conf

С newConfFile содержит конфигурацию виртуального хоста, которую вы хотите добавить

Это функция Bash для проверки, существует ли функция

#return 0 if command exist else return 1
canExec()
{
type "$1" &> /dev/null ;
}

например canExec sed проверьте, существует ли команда sed в вашей системе

С awk, как насчет:

  • сохранить каждую строку в переменной для "предыдущей строки"
  • если текущая строка совпадает со второй, которую вы ищете (DirectoryIndex), проверьте переменную с предыдущей строкой
  • Если они оба совпадают
    • распечатать bumpf
    • распечатать текущую строку
    • напечатайте проглоченный '#'
  • Еще
    • распечатать текущую строку
  • обновить переменную "предыдущая строка" текущей строкой.

Это должно сработать для вас, потому что вам не нужно строго ПРЕДУПРЕЖДЕНИЕ текста - поскольку и текст, который вы ищете, и текст, который вы вставляете, начинаются с # вы можете оставить оригинал #, вставьте свой текст минус первый # линию посередине, затем распечатайте исходную вторую строку, затем распечатайте другую # быть тем, кого вы не приготовили.

Вам нужно будет заполнить полный текст, но здесь достаточно, чтобы убедить меня, что это может сработать;)

gawk "{if (a==\"#\" && /^# DirectoryIndex/) {print \"# Allow Server\n#With the URL\n#\"; print $0} else {print $0}} {a=$0}" httpd.conf > ??

(Мои экраны с двойными кавычками предназначены для командной строки Windows. При необходимости отрегулируйте).

Отредактированная цитата для bash:

gawk '{if (a=="#" && /^# DirectoryIndex/) {print "# Allow Server\n# With the URL\n#"; print $0} else {print $0}} {a=$0}' httpd.conf