【问题标题】:Delete duplicate consecutive lines without sort or unique in xml file删除重复的连续行,没有排序或在 xml 文件中唯一
【发布时间】:2015-03-04 21:54:06
【问题描述】:

我有一个 xml 文件,我需要在其中保持标签的顺序,但有一个名为 media 的标签,它具有连续顺序的重复行。我想删除一个重复的媒体标签,但想保留所有的父标签 - (它们也是连续的和重复的)。我想知道是否有一个 awk 解决方案仅在模式匹配时才删除。例如:

<story>
   <article>
      <media>One line</media>
      <media>One line</media>    <-- Same line as above, want to delete this
      <media>Another Line</media>
      <media>Another Line</media>  <-- Another duplicate, want to delete this
   </article>
</story>
<story>
   <article>
     ........ and so on

我想保留连续的故事和文章标签,只删除媒体标签的重复项。我尝试了许多 awk 脚本,但如果不对文件进行排序并破坏 xml 的顺序,似乎什么都不起作用。非常感谢任何帮助。

【问题讨论】:

  • 不是一个明确的例子。请将您的 as above 符号移动到您的 cmets 中。

标签: regex xml bash awk sed


【解决方案1】:

一个 awk 脚本会帮助你

awk '!(f == $0){print} {f=$0}' input

测试

$ cat input
<story>
   <article>
      <media>One line</media>
      <media>One line</media>
      <media>Another Line</media>
      <media>Another Line</media>
this
   </article>
</story>
<story>
   <article>

$ awk '!(f == $0){print} {f=$0}' input
<story>
   <article>
      <media>One line</media>
      <media>Another Line</media>
this
   </article>
</story>
<story>
   <article>

$ awk 'f!=$0&&f=$0' input

感谢吉德

【讨论】:

  • 较短的awk 'f!=$0&amp;&amp;f=$0'
  • @Jidder 那更短了
【解决方案2】:

使用需要正常排序文件的 uniq 行为,删除重复行,完全遵循上一行

uniq YourFile

【讨论】:

  • 这不会删除所有重复的标签吗?
  • 您说得对,请求中并不清楚。在这里,它删除所有重复的连续行,无论它是什么(标签与否)。这主要是一半不看标签的回复中所做的。请求是删除行,它解释了示例中带有媒体标签的情况。因此,如果出现另一种重复的行,并且不应将其删除,则我的解决方案是不合适的(例如 HTML 中的 2 行
    )。
【解决方案3】:

考虑文件:

$ cat file
<story>
   <article>
      <media>One Line</media>
      <media>One Line</media>
      <media>Another Line</media>
      <media>Another Line</media>
   </article>
</story>
<story>
   <article>
     ........ and so on

要删除重复的媒体行并且只删除重复的媒体行:

$ awk '/<media>/ && $0==last{next} {last=$0} 1' file
<story>
   <article>
      <media>One Line</media>
      <media>Another Line</media>
   </article>
</story>
<story>
   <article>
     ........ and so on

工作原理

  • /&lt;media&gt;/ &amp;&amp; $0==last{next}

    任何带有&lt;media&gt; 标签并且 与前一行匹配的行都会被跳过:命令next 告诉awk 跳过所有剩余的命令并从下一个重新开始 行。

  • last=$0

    这会将最后一行完整地保存在变量 last 中。

  • 1

    这是神秘的awk 表示法,表示打印当前行。如果您更喜欢简洁而不是简洁,可以将1 替换为{print $0}

【讨论】:

  • 谢谢!像魅力一样工作!
  • 较短的awk '!/&lt;media&gt;/||$0!=last&amp;&amp;last=$0'
  • 感谢您的简明解释。 AWK对我来说有点难,你的详细信息帮助我解决了另一个问题:stackoverflow.com/questions/50071125/…
【解决方案4】:

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

sed -r 'N;/^(\s*<media>.*)\n\1$/!P;D' file

这会删除以&lt;media&gt; 标记开头的重复行。

注意这会从前面删除行,但由于它们是重复的,所以这无关紧要。

【讨论】:

    猜你喜欢
    • 2011-02-13
    • 2020-04-30
    • 1970-01-01
    • 2015-06-07
    • 2012-10-07
    • 2018-08-11
    • 2020-03-30
    • 2021-12-20
    • 2014-04-05
    相关资源
    最近更新 更多