Vim 或 Sed 中的复杂搜索和替换

Vim 或 Sed 中的复杂搜索和替换

我有以下内容(从我的寄存器中删除以保留格式,因为这可能是我在这里的原因):

<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> 

我希望它变成:<li> Concrete Patching (flag) </li>,就是这样。

编辑: 应该提到的是,每个标签内的字符串<li><span> (...可以是任何字符串。我想删除<span>每个中的首字母<li>,保留所有 up to (,然后将所有 up to 替换)flag。抱歉没有澄清。


这种模式出现在目录中的所有文件中,因此使用批处理作业sed将是理想的选择,但我对此并不那么有信心。我已经尝试在单个Vim缓冲区中使用:%s/<C-r>"将拉出的寄存器放入命令中,转义我知道要转义的内容(例如<\/span>换行符\r),但我绝对没有正确执行。

如果有一个插件可以轻松地:%s从上面这样的复杂的拉取块中完成,我会使用它,但它们似乎都不尊重按照我需要的方式正确执行所需的正则表达式模式。

我在工作中替换了许多几乎相同的文本,并且手动编辑需要花费数小时的时间,而我知道使用正则表达式模式可能需要几分钟的时间。请随时提出任何建议。

答案1

我建议采用以下-z选项sed

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

这考虑到“具体修补”可以是任何字符串。

-z, --null-data
                 separate lines by NUL characters

答案2

这将做到这一点:

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

它的工作方式如下:

  • 对于包含 的任何行Concrete Patching,执行以下 2 次替换:1) 将第一个替换<span>为空格,2) 将第一个替换 (<\/span><span/(flag) <\li>

一旦您确认它执行了您想要的操作,只需添加即可-i就地进行替换:

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

相关内容