1

I have the following (yanked from my register to retain formatting, as it's probably the reason I'm here):

<li><span>Concrete Patching (</span><span
        style="overflow: hidden; display: inline-block; margin: 0.00px 0.00px; border: 0.00px solid #000000; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); width: 16.00px; height: 16.00px;"><img
          alt=""
          src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4XmP4//8dAwAI2gLt+1m1FgAAAABJRU5ErkJggg=="
          style="width: 16.00px; height: 16.00px; margin-left: -0.00px; margin-top: -0.00px; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);"
          title=""></span>)</li>
    <li><span>Paving (</span><span
        style="overflow: hidden; display: inline-block; margin: 0.00px 0.00px; border: 0.00px solid #000000; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); width: 16.00px; height: 16.00px;"><img
          alt=""
          src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4XmP4//8tAwAI2ALsJ7n0vAAAAABJRU5ErkJggg=="
          style="width: 16.00px; height: 16.00px; margin-left: -0.00px; margin-top: -0.00px; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);"
          title=""></span>)</li> 

I would like that to become: <li> Concrete Patching (flag) </li>, that's it.

EDIT: Should mention that the string inside of each <li><span> (... tag could any string. I want to remove the initial <span> within each <li>, retain all up to (, then replace all up to ) with flag. Sorry for not clarifying.


This pattern occurs throughout all files in a directory, so a batch job using sed would be ideal, but I'm not as confident with that. I've attempted it within a single Vim buffer utilizing :%s/<C-r>" to put the yanked register in the command, escaping what I know to escape (eg. <\/span>, \r for line break) but I'm defintely not doing it correctly.

If there's a plugin for easily doing :%s from a complicated yanked chunk like the above, I'd use it but none of them seem to respect regex patterns needed to properly do so the way I need.

I replace a lot of near identical text in my work and doing manual edits takes hours of time when I know it could take minutes with a regex pattern. Please feel free to offer any suggestions.

8
  • 1
    I'm assuming that you just want the first line to be changed and leave the rest of the block as is? Or do you want to replace the entire block in the input example with the single line?
    – mattb
    Jul 12 at 22:08
  • I think my answer is wrong, unaccept it so I can reformulate it. Jul 12 at 23:17
  • confirmed @schrodigerscatcuriosity lol Jul 12 at 23:18
  • @schrodigerscatcuriosity I edited my question a bit better, hopefully it makes more sense - sorry about that Jul 12 at 23:31
  • You have two similar blocks, <li><span>Concrete Patching... and <li><span>Paving ..., shouldn't be the output <li> Concrete Patching (flag) </li><li> Paving (flag) </li>? Jul 12 at 23:37
2

I propose this approach, using the -z option of sed:

$ sed -z 's;<li><span>\([^(]*\)(</span><span[^<]*<img[^>]*></span>);<li> \1(flag) ;g' file
<li> Concrete Patching (flag) </li>
    <li> Paving (flag) </li> 

This takes into account that "Concrete Patching" could be any string.

-z, --null-data
                 separate lines by NUL characters
1
  • this worked, as far as I can tell at least - you're a life saver Jul 13 at 19:49
0

This will do it:

sed '/Concrete Patching/ s/<span>/ /; s/(<\/span><span/(flag) <\/li>/' your_file

The way it's working is as follows:

  • For any line containing Concrete Patching, perform the following 2 substitutions: 1) replace the first <span> with a space and 2) replace the (<\/span><span/ with (flag) <\li>

Once you've confirmed it does what you want, just add the -i to do the substitution in-place:

sed -i '/Concrete Patching/ s/<span>/ /; s/(<\/span><span/(flag) <\/li>/' your_file
3
  • Thank you! This is going to save me hours of time, I'll try it out now. Is there a way to tell sed to retain the '/Concrete Patching/' part, as if it was just a simple string? That's the only part that'd be different throughout. Jul 12 at 22:50
  • @WilliamGreer Do you mean "Concrete Patching" could be other string? Jul 12 at 23:00
  • @schrodigerscatcuriosity yes exactly Jul 12 at 23:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.