【发布时间】:2016-02-02 21:38:26
【问题描述】:
使用 sed/awk,我需要删除文件中从第一次出现 pattern1 到(但不包括)最后一次出现 pattern2 的所有行。
考虑以下文本:
<entity name="good">
</entity>
<entity name="bad">
stuff to delete
</entity>
<entity name="bad">
stuff to remove
</entity>
<entity name="bad2">
</entity>
<entity name="deleteMe2">
</entity>
<entity name="bad2">
</entity>
<entity name="good">
</entity>
我想要以下结果
<entity name="good">
</entity>
<entity name="bad2">
</entity>
<entity name="good">
</entity>
我知道如何在 sed 中设置范围,但不知道如何匹配最后一次出现的 'bad2' 并且不将其包含在删除中。下面当然不会起作用,因为它将匹配第一个 bad2 并且不会删除 'deleteme2' 或 'bad2' 的第二个出现。
sed -i '/<entity name="bad"/,/<entity name="bad2"/d' file.xml
我正在处理的文件中可能有数百行“坏”/“deleteMe2”/“坏2”行,因此简单的行数不起作用。如果这是多个命令(它不必只是一个),我很好,但是效率越高越好,因为被修改的文件可能非常大。同样, -i 是因为我想就地删除它们之间的线。
注意:我对 SED 比对 AWK 更熟悉,但我愿意接受所有可以得到的帮助:)
【问题讨论】:
-
看起来很像 XML。是 XML 吗?因为如果是这样,使用解析器几乎肯定会更好。
-
是的,它是 XML,我完全不使用 sed/awk 来修改 XML,但是在这种情况下 XML 定义非常简单。从字面上看,你在上面看到的还有一些额外的文字。我没有真正提到的一个限制是我很可能必须在 Windows 机器上执行此操作,最有可能使用 gnused 或 gawk。如果在 sed/awk 中无法执行我所要求的操作,我会考虑将 perl 作为一种选择。
-
当您在问题中重复标题时,问题会更加清晰。我先跳过标题,然后一头雾水。
-
您需要删除和保留哪些部分?从您的“结果”中不清楚,它删除了 2 个坏部分、1 个 bad2 部分和 1 个 deleteMe2 部分。
-
@Brian 删除带有 bad 的第一行和所有后续行,直到最后一个 bad2 部分完成。中间的一切都很糟糕。