Text-Processing

使用 sed 在每個 html <ul> 中將最後一行放在首位

  • April 2, 2019

每次出現“ul”時,我嘗試將“名稱:*****”行放在相應的(最裡面的)“ul”之後,這樣它看起來像這樣:

前:

&lt;ul&gt;
  &lt;ul&gt;
     &lt;li href="https://www.deepl.com/translator"&gt;DeepL&lt;/li&gt;
     &lt;li href="https://translate.google.com"&gt;Google Trad&lt;/li&gt;
     name: "Translate",
  &lt;/ul&gt;
  &lt;li href="https://www.youtube.com/feed/subscriptions"&gt;Youtube&lt;/li&gt;
  &lt;ul&gt;
     &lt;li href="https://www.facebook.com/"&gt;Facebook&lt;/li&gt;
     &lt;li href="https://twitter.com/"&gt;Twitter&lt;/li&gt;
     &lt;li href="https://www.instagram.com"&gt;Instagram&lt;/li&gt;
     &lt;li href="https://discordapp.com"&gt;Discord&lt;/li&gt;
     name: "Network",
  &lt;/ul&gt;
  name: "Fav",
&lt;/ul&gt;

後:

&lt;ul&gt;
  name: "Fav",
  &lt;ul&gt;
     name: "Translate",
     &lt;li href="https://www.deepl.com/translator"&gt;DeepL&lt;/li&gt;
     &lt;li href="https://translate.google.com"&gt;Google Trad&lt;/li&gt;
  &lt;/ul&gt;
  &lt;li href="https://www.youtube.com/feed/subscriptions"&gt;Youtube&lt;/li&gt;
  &lt;ul&gt;
     name: "Network",
     &lt;li href="https://www.facebook.com/"&gt;Facebook&lt;/li&gt;
     &lt;li href="https://twitter.com/"&gt;Twitter&lt;/li&gt;
     &lt;li href="https://www.instagram.com"&gt;Instagram&lt;/li&gt;
     &lt;li href="https://discordapp.com"&gt;Discord&lt;/li&gt;
  &lt;/ul&gt;
&lt;/ul&gt;

所以,我已經測試了很多東西,比如:

sed -i -e 'N;s/&lt;ul&gt;\([.\n]*\)\n\(.*\),/\2\n\1' fav.html

這和我現在發現的所有東西都不起作用,因為最後一個“ul”後面的“名稱”並不總是要替換的。如果有人有想法,我很樂意聽到。

這在sed. (挑戰已經發出;我等待被證明是錯誤的。)如果您特別需要sed解決方案,您不妨停止閱讀本文。

我能夠通過 和 的組合來做到這tac一點awk

tac fav.html | awk '
   /&lt;\/ul&gt;/    { flag=1;            level++; }
   /&lt;ul&gt;/      { print save[level]; level--; }
   flag  &&  /name/    { flag=0; save[level] = $0; next; }
               { print; }
   ' | tac &gt; fav.html.new  &&  mv fav.html.new fav.html

tac fav.html``fav.html逐行反轉(tac向後cat拼寫),因此產生

&lt;/ul&gt;
  name: "Fav",
  &lt;/ul&gt;
     name: "Network",
     &lt;li href="https://discordapp.com"&gt;Discord&lt;/li&gt;
          ︙
  &lt;ul&gt;
   ︙
  &lt;ul&gt;
&lt;ul&gt;

程式碼的前兩行awk計算&lt;ul&gt;嵌套級別。由於它們是相反&lt;/ul&gt;的順序,因此增加水平並 &lt;ul&gt;降低它。當我們看到 a &lt;/ul&gt;時,我們設置flag為表示我們正在 &lt;ul&gt;從底部進入一個塊。當我們在name一個塊的底部附近 找到一個時&lt;ul&gt;,我們保存它,然後跳到該next行(不列印該name行)。當我們找到一個 &lt;ul&gt;(即一個 &lt;ul&gt;塊的開頭)時,我們在列印它本身name之前列印保存的內容。&lt;ul&gt;

finaltac再次反轉這些行,將它們中的大部分放回原來的位置,並將每個放在name 對應&lt;ul&gt;.

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