【问题标题】:How to delete duplicate lines from a block using sed [duplicate]如何使用 sed 从块中删除重复行 [重复]
【发布时间】:2021-12-13 01:29:11
【问题描述】:

假设我们有如下示例所示的一行代码:

<segment1>
    <element="1" prop="blah"/>
    <element="2" prop="blah"/>
    .
    .
</segment1>

<segment2>
    <element="1" prop="blah"/>
    <element="2" prop="blah"/>
    .
    .
    <element="1" prop="blah"/>
    <element="2" prop="blah"/>
</segment2>

<segment3>
    <element="1" prop="blah"/>
    <element="2" prop="blah"/>
    .
    .
</segment3>

例如,此处的段 2 有重复项,需要删除(此处排序无关紧要)。那么现在如何绑定 sed 以仅从段 2 中删除重复项。 在此示例中,段 2 是第二段,可能并非所有可能的情况都如此,因为它也可能是子集的子集。

我对此的想法是使用标签,以命令gsed -ni 'G; s/\n/&amp;&amp;/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'开始和结束

【问题讨论】:

  • 标准建议:Don't Parse XML/HTML with regular expressions;而是使用 XML 解析器,例如 DOMSAXStAXXSLT
  • ... 和 XSLT 处理器将非常适合此任务,而 sed 则不是,即使我们假设 XML 输入的格式严格规则。
  • 例如,仅从段 2 中删除 specifically 可以很容易地保证输入的格式,但让sed 自己弄清楚它需要从段 2 中删除,或者哪些特定的行,如果可能的话,将是非常困难的。
  • 如果我们使用 start 和 end 关键字来绑定区域,而不是遵循格式化的输入呢?

标签: xml bash sed command-line gnu-sed


【解决方案1】:

这可能对你有用(GNU sed):

sed -E '/<segment2>/,/<\/segment2>/{G;/^([^\n]*)(\n.*)*\n\1(\n|$)/!{P;h};d}' file

使用介于&lt;segment2&gt;&lt;/segment2&gt; 之间的范围。

将范围内已经看到的内容的副本附加到当前行,如果没有看到,则打印当前行并复制。

否则,删除该行。

【讨论】:

  • 适用于 x64 但不适用于 arm64(busybox)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-19
  • 1970-01-01
  • 2021-12-11
相关资源
最近更新 更多