Отфильтровать HTML-тег и заменить его другими HTML-тегами с помощью sed

Отфильтровать HTML-тег и заменить его другими HTML-тегами с помощью sed

Я заменял <B>и </B>на <STRONG>и </STRONG>в файле. Это немного похоже на замену тегов hmtl. Я использовал sed 's/\<B\>/STRONG/g'. Это сработало, но если в файле присутствует [B]и [/B]. Тогда они также меняются на [STRONG]и [/STRONG]. Я не понимаю логику этого.

решение1

По умолчанию sed использует базовые регулярные выражения. Это означает, что GNU позволяет \<сопоставлять начало слова и \>сопоставлять конец слова. Обратите внимание:

$ echo '<B> BBB B' | sed 's/\<B\>/STRONG/g'
<STRONG> BBB STRONG

\<B\>соответствует слову B, которое встречается дважды в строке выше. Поскольку оно соответствует слову B, а не угловым скобкам, угловые скобки остаются неизменными.

Если вы хотите сопоставить угловые скобки, <>оставьте обратную косую черту без нее:

$ echo '<B> BBB B' | sed 's/<B>/<STRONG>/g'
<STRONG> BBB B

<B>соответствует открывающей угловой скобке, за которой Bследует закрывающая угловая скобка. Таким образом, <B>заменяется на <STRONG>но Bостается один.

Перехватываем как открывающие, так и закрывающие теги

$ echo '<B> BBB B </B>' | sed -r 's|<(/)?B>|<\1STRONG>|g'
<STRONG> BBB B </STRONG>

-rдля расширенных регулярных выражений, но последние версии GNU sed также поддерживают -Eкак синоним -r. BSD sed использует -Eдля этого и, как сообщается, будущие стандарты POSIX приняли -E. Таким образом, для совместимости можно использовать (спасибо @Kos):

$ echo '<B> BBB B </B>' | sed -E 's|<(/)?B>|<\1STRONG>|g'
<STRONG> BBB B </STRONG>

решение2

<и >не являются специальными символами вБазовые регулярные выражения, поэтому их не следует экранировать. Когда вы экранируете их, sedони будут пытаться обрабатываться как специальные символы, и тогда поведение будетнеопределенный:

Интерпретация обычного символа, которому предшествует ( '\' ), не определена, за исключением:

Поэтому просто используйте <and >без экранирования:

$ echo 'b<b>' | sed 's/<b>/strong/'  
bstrong

решение3

Решение с awk. Здесь у меня есть пример файла с двумя строками, которые содержатитеги и используем gsubфункцию для их замены. Затем выводим это во временный файл и обратно в исходный файл. Удаляем временный файл, когда закончим. Адаптируем по мере необходимости.

$ cat tags.txt                                                                                                                                      
<B> and </B>
<B> or </B>

$ awk '{gsub("<B>","<STRONG>"); gsub("</B>","</STRONG>");print}' tags.txt                                                                           
<STRONG> and </STRONG>
<STRONG> or </STRONG>

$ awk '{gsub("<B>","<STRONG>"); gsub("</B>","</STRONG>");print}' tags.txt > tmpfile.txt && cat tmpfile > tags.txt

Связанный контент