Замена текста между двумя комментариями HTML

Я новичок в мире sed / awk и regex в целом и изучал их использование, но барахтался, пытаясь удовлетворить мою потребность:

У меня есть страница htm которой есть однострочное уведомление, которое должно быть обновлено с введенным пользователем текстом (через скрипт оболочки) между двумя комментариями, действующими как теги, например:

 <!--BeginNoticeMSG-->NOTICE: This is a notice<!--EndNoticeMSG--> 

Пользователь, введенный текст (хранящийся в переменной, назовем его $NEWNOTICE ), затем должен будет заменить то, что находится между тегами, так эффективно:

 <!--BeginNoticeMSG-->$NEWNOTICE<!--EndNoticeMSG--> 

Который будет вставлен в файл htm как (например):

 <!--BeginNoticeMSG-->This is a test notice<!--EndNoticeMSG--> 

Как я могу правильно определить и заменить текст между тегами?

2 Solutions collect form web for “Замена текста между двумя комментариями HTML”

Это (совершенно) основной рецепт, который будет отвечать вашим потребностям только точно так:

 #!/bin/bash REPLACEWITH="Your replacement text here" STARTTAG="BeginNoticeMSG" ENDTAG="EndNoticeMSG" sed -E "s/(<\!\-\-$STARTTAG\-\->)(.*)(<\!\-\-$ENDTAG\-\->)/\1$REPLACEWITH\3/" -i target_file.html 

Он будет разбиваться по-разному, если вход отличается, особенно если входной тег разбит на несколько строк.

Использование регулярных выражений обычно не рекомендуется для обработки HTML и XML (я понимаю, что это всего лишь комментарий), но … Если ваш ввод настолько надежен, как намекнул в этом сообщении, то это простое может сделать трюк.

В этом случае я ссылаюсь на части вашего тега как \1 и \3 (которые коррелируют с элементами в скобках в регулярном выражении), чтобы уменьшить количество текста, необходимого для ввода замены.

Или без опции -E и без обратных ссылок:

 #!/bin/bash REPLACEWITH="Text to replace with here" STARTTAG="BeginNoticeMSG" ENDTAG="EndNoticeMSG" sed -e "s/<\!\-\-$STARTTAG\-\->.*<\!\-\-$ENDTAG\-\->/<\!\-\-$STARTTAG\-\->$REPLACEWITH<\!\-\-$ENDTAG\-\->/" -i target_file.html 

Предполагая, что у вас никогда не будет более одного уведомления в одной строке (точнее, у вас никогда не будет более одного появления <!--BeginNoticeMSG--> или из <!--EndNoticeMSG--> в той же строке):

 sed -e "s&\(<!--BeginNoticeMSG-->\).*\(<!--EndNoticeMSG-->\)&\1$NEWNOTICE\2&" 

Если комментарии начала и окончания могут отличаться, вы можете написать для них регулярное выражение.

Обратите внимание, что это работает, только если вы уверены, что $NEWNOTICE не содержит \ , & или новую $NEWNOTICE , поскольку в противном случае эти символы интерпретируются как синтаксис sed.

Чтобы быть надежным с символами пунктуации, используйте awk вместо этого.

 export NEWNOTICE awk '{sub(/<!--BeginNoticeMSG-->.*<!--EndNoticeMSG-->/, "<!--BeginNoticeMSG-->" env[NEWNOTICE] "<!--EndNoticeMSG-->"); print}' 
  • Как распечатать строку, если эта строка или следующая строка не содержат определенную строку
  • Извлечение данных в linux / unix
  • Как вставить текст перед первой строкой файла?
  • Извлечение строк между специальными символами
  • Насколько хорошо работает grep / sed / awk на очень больших файлах?
  • Рекурсивно заменить строку в файлах
  • Подмена текста внутри сжатых файлов
  • создать файл XML с помощью сценария bash
  • grep и sed в конкретных
  • С помощью sed я хочу заменить первый блок текста, который соответствует
  • Как эффективно выражать переменные для SED?
  • Linux и Unix - лучшая ОС в мире.