每次出现“ul”时,我尝试将“name: *****”行放在相应的(最里面包含的)“ul”之后,这样它看起来像这样:
前:
<ul>
<ul>
<li href="https://www.deepl.com/translator">DeepL</li>
<li href="https://translate.google.com">Google Trad</li>
name: "Translate",
</ul>
<li href="https://www.youtube.com/feed/subscriptions">Youtube</li>
<ul>
<li href="https://www.facebook.com/">Facebook</li>
<li href="https://twitter.com/">Twitter</li>
<li href="https://www.instagram.com">Instagram</li>
<li href="https://discordapp.com">Discord</li>
name: "Network",
</ul>
name: "Fav",
</ul>
后:
<ul>
name: "Fav",
<ul>
name: "Translate",
<li href="https://www.deepl.com/translator">DeepL</li>
<li href="https://translate.google.com">Google Trad</li>
</ul>
<li href="https://www.youtube.com/feed/subscriptions">Youtube</li>
<ul>
name: "Network",
<li href="https://www.facebook.com/">Facebook</li>
<li href="https://twitter.com/">Twitter</li>
<li href="https://www.instagram.com">Instagram</li>
<li href="https://discordapp.com">Discord</li>
</ul>
</ul>
所以,我已经测试了很多东西,比如:
sed -i -e 'N;s/<ul>\([.\n]*\)\n\(.*\),/\2\n\1' fav.html
这和我现在发现的所有内容都不起作用,因为最后一个“ul”后面的“name”并不总是要替换的。如果有人有想法,我很乐意听到。
答案1
这在 中可能是不可能的sed
。 (挑战已经发出;我正在等待被证明是错误的。)如果您特别需要sed
解决方案,您最好停止阅读本文。
我能够通过tac
和 的组合来做到这一点awk
:
tac fav.html | awk '
/<\/ul>/ { flag=1; level++; }
/<ul>/ { print save[level]; level--; }
flag && /name/ { flag=0; save[level] = $0; next; }
{ print; }
' | tac > fav.html.new && mv fav.html.new fav.html
tac fav.html
fav.html
逐行反转(向后tac
拼写cat
),因此产生
</ul>
name: "Fav",
</ul>
name: "Network",
<li href="https://discordapp.com">Discord</li>
︙
<ul>
︙
<ul>
<ul>
代码的前两行awk
计算<ul>
嵌套级别。由于它们的顺序相反,因此</ul>
会增加级别并 <ul>
降低级别。当我们看到 a 时 </ul>
,我们设置flag
表示我们正在 <ul>
从底部进入一个块。当我们在块name
的底部附近 找到 a<ul>
时,我们将其保存,并跳到该next
行(不打印该name
行)。当我们找到a <ul>
(即块的开头 <ul>
)时,我们name
在打印<ul>
本身之前打印保存的内容。
决赛tac
再次颠倒了线路,将大部分线路放回原来的位置,并将每条线路都放回原来的位置。name
后其对应的<ul>
.