
Я заменял <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
они будут пытаться обрабатываться как специальные символы, и тогда поведение будетнеопределенный:
Интерпретация обычного символа, которому предшествует ( '\' ), не определена, за исключением:
- Символы ')', '(', '{' и '}'
- Цифры от 1 до 9 включительно (см.BRE, соответствующие нескольким символам)
- Символ внутри выражения в квадратных скобках
Поэтому просто используйте <
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