Search code examples
bashsedreplace

How to replace string depending on whether it is odd or even


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

Solution

  • 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