使用 sed 删除多行模式

问题描述 投票:0回答:1

我有一个 AsciiDoc 文件,想要在使用 asciidoctor-pdf 将其渲染为 PDF 之前删除所有 可折叠块

.Click to reveal the answer
[%collapsible]
====
This is the answer.
====

点后面的文字可以是任意标题。

我尝试使用

sed '/\.(.* )\n\[\%collapsible\]/d;/====/,/====/d'
首先删除标题和
[%collapsible]
字符串,然后删除
====
部分之间的内容,但我无法设法使换行符匹配。

awk sed asciidoc asciidoctor
1个回答
0
投票

sed
一次匹配一行,因此简单的脚本不可能匹配任何带有嵌入换行符的内容。

虽然您可以编写

sed
脚本来收集前一行和当前行,然后与它们进行匹配,但 Awk 可能是处理重要文件的更好工具。

awk 'BEGIN { RS=ORS="===="}
/(^|\n)\.[^\n]*\n\[%collapsible]/{
  sub(/(^|\n)\.[^\n]*\n\[%collapsible]/, ""); print; p=1; next }
!(p && p--)' file

BEGIN
部分将记录分隔符和输出记录分隔符设置为
"===="
。通过此设置,Awk 会将这些分界符之间的行作为一条记录(或“行”)处理,因此其余处理变得相当容易。

简而言之,如果当前记录包含正则表达式的匹配项,我们会将该部分替换为空,并将

p
设置为 1。我们打印余数,然后跳到下一条记录。

对于下一条记录,

p
将为1,因此我们跳过它,但我们也会递减
p
,以便之后的下一条记录它将再次为0。

如果

[%collapsible]
文本不是紧接在分隔符之前,这可能无法正常工作。如果您需要更详细地控制该行为,可能会发布更详细的要求。

演示:https://ideone.com/0FwN64

这个简单的演示还在末尾添加了一个

====
,您可能不想要它。同样,更复杂的行为是可能的,但可能需要更复杂的要求。

© www.soinside.com 2019 - 2024. All rights reserved.