I m trying to replace a string "::" on a plain text for <b> or </b>. Depending of the first or second match without result with sed. The goal here is that the second tag </b> can be at the end of a paragraph not at the end of a line. i.e:
::Habiéndose calmado de distracciones, uno permanece completamente,
y la naturaleza superior es vista con los ojos de la sabiduría.::
must be
<b>Habiéndose calmado de distracciones, uno permanece completamente,
y la naturaleza superior es vista con los ojos de la sabiduría.</b>
I try it without result:
sed "s|::\(.*\)|\\<b>\1\</b>|g" EntrenamientoProgresivoSamadhi
Thank you in Advantage
CodePudding user response:
Assumptions:
::
can occur more than once on a given line of input::
never shows up as data (ie, we need to replace all occurrences of::
)- a solution using
awk
is acceptable
Adding some more data to our input:
$ cat file
::Habiéndose calmado de distracciones, uno permanece completamente,
y la naturaleza superior es vista con los ojos de la sabiduría.::
some more ::text1:: and then some more ::text2:: the end
One awk
idea:
awk '
BEGIN { tag[0]="<b>"; tag[1]="</b>" }
{ while (sub(/::/,tag[c%2])) c ; print }
' file
This generates:
<b>Habiéndose calmado de distracciones, uno permanece completamente,
y la naturaleza superior es vista con los ojos de la sabiduría.</b>
some more <b>text1</b> and then some more <b>text2</b> the end
CodePudding user response:
Using GNU sed
$ sed -Ez 's~::(.[^:]*)::~<b>\1</b>~' input_file
<b>Habiéndose calmado de distracciones, uno permanece completamente,
y la naturaleza superior es vista con los ojos de la sabiduría.</b>
CodePudding user response:
Use awk
and increment a counter variable. Then you can perform a different substitution depending on whether it's odd or event.
awk '/::/ && counter % 2 == 0 {sub("::", "<b>") }
/::/ {sub("::", "</b>") }
1'
Note that this will only work correctly if the start and end ::
are on different lines.
CodePudding user response:
This might work for you (GNU sed):
sed ':a;/::/{x;s/^/x/;/xx/{s///;x;s/::/<\/b>/;ba};x;s/::/<b>/;ba}' file
If a line contains ::
, swap to the hold space and increment a counter by inserting an x
at the start of the line.
If the counter is 2 i.e. the swap space contains xx
, reset the counter and then swap back to the pattern space and replace ::
by <\b>
and go again (in the case that a line contains 2 or more ::
strings).
Otherwise, swap back to the pattern space and replace ::
by <b
and go again (for reasons explained above).
All other lines are untouched.