Sed

Vim 或 Sed 中復雜的搜尋和替換

  • July 13, 2021

我有以下內容(從我的寄存器中拉出以保留格式,因為這可能是我在這裡的原因):

<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>,保留所有最多替換(所有最多。很抱歉沒有澄清。)``flag


這種模式出現在目錄中的所有文件中,因此使用批處理作業sed是理想的,但我對此沒有信心。我已經嘗試在單個Vim緩衝區中使用它:%s/<C-r>"來將 yanked 寄存器放入命令中,轉義我知道要轉義的內容(例如<\/span>\r換行),但我肯定沒有正確執行。

如果有一個外掛可以輕鬆地:%s從像上面這樣的複雜的 yanked 塊中進行操作,我會使用它,但它們似乎都不尊重按照我需要的方式正確執行此操作所需的正則表達式模式。

我在工作中替換了很多幾乎相同的文本,並且手動編輯需要花費數小時的時間,而我知道使用正則表達式模式可能需要幾分鐘。請隨時提供任何建議。

我提出了這種方法,使用以下-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

這將做到:

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

引用自:https://unix.stackexchange.com/questions/658135