
Eu estava substituindo <B>
e </B>
por <STRONG>
e </STRONG>
em um arquivo. É como substituir tags HTML. Eu usei sed 's/\<B\>/STRONG/g'
. Ele fez o trabalho, mas está em arquivo [B]
e [/B]
está presente. Então também eles são transformados em [STRONG]
e [/STRONG]
. Eu não entendo a lógica por trás disso.
Responder1
Por padrão, sed usa expressões regulares básicas. Isso significa que o GNU permite \<
combinar o início de uma palavra e \>
o final de uma palavra. Observar:
$ echo '<B> BBB B' | sed 's/\<B\>/STRONG/g'
<STRONG> BBB STRONG
\<B\>
corresponde à palavra B
que aparece duas vezes na string acima. Como corresponde à palavra B
e não aos colchetes angulares, os colchetes angulares permanecem inalterados.
Se você quiser corresponder colchetes angulares, <>
deixe a barra invertida desativada:
$ echo '<B> BBB B' | sed 's/<B>/<STRONG>/g'
<STRONG> BBB B
<B>
corresponde ao colchete angular aberto seguido B
pelo colchete angular de fechamento. Assim, <B>
é substituído, <STRONG>
mas B
é deixado em paz.
Capturando as tags de abertura e fechamento
$ echo '<B> BBB B </B>' | sed -r 's|<(/)?B>|<\1STRONG>|g'
<STRONG> BBB B </STRONG>
-r
é para regex estendido, mas versões recentes do GNU sed também suportam -E
como sinônimo de -r
. O BSD sed usa -E
para isso e, supostamente, os futuros padrões POSIX adotaram -E
. Assim, para compatibilidade, pode-se querer usar (gorjeta @Kos):
$ echo '<B> BBB B </B>' | sed -E 's|<(/)?B>|<\1STRONG>|g'
<STRONG> BBB B </STRONG>
Responder2
<
e >
não são caracteres especiais emExpressões regulares básicas, então eles não devem ser escapados. Quando você escapou deles, sed
tentará tratá-los como caracteres especiais, e então o comportamento seráindefinido:
A interpretação de um caractere comum precedido por um ( '\' ) é indefinida, exceto para:
- Os caracteres ')', '(', '{' e '}'
- Os dígitos de 1 a 9 inclusive (verBREs que correspondem a vários caracteres)
- Um caractere dentro de uma expressão entre colchetes
Então é só usar <
e >
sem fugir:
$ echo 'b<b>' | sed 's/<b>/strong/'
bstrong
Responder3
Solução com awk
. Aqui eu tenho um arquivo de exemplo com duas linhas que contémetags e use gsub
a função para substituí-las. Em seguida, enviamos isso para o arquivo temporário e de volta ao arquivo original. Remova o arquivo temporário quando terminar. Adapte conforme necessário.
$ 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