【问题标题】:How to remove duplicate lines from a file如何从文件中删除重复的行
【发布时间】:2018-04-07 04:12:26
【问题描述】:

我有一个生成测试和预测输出的工具。这个想法是,如果我失败了,我可以将预测与实际输出进行比较,看看它们在哪里分歧。问题是实际输出包含一些行两次,这使diff 感到困惑。我想删除重复项,以便我可以轻松地比较它们。基本上,类似sort -u 但没有排序。

有没有 unix 命令行工具可以做到这一点?

【问题讨论】:

标签: unix command-line duplicates


【解决方案1】:

uniq 答案的补充,如果您不介意先sorting 您的文件,这将非常有用。如果您需要删除不相邻的行(或者如果您想在不重新排列文件的情况下删除重复项),则应该使用以下 Perl 单行代码(从here 窃取):

cat textfile | perl -ne '$H{$_}++ or print'

【讨论】:

  • 我认为这是一个很好的答案。用 Perl 编程大约 6 年了,没想到这么简洁
  • Perl 部分非常漂亮。但是,这确实有资格获得“猫的无用使用”奖:-)(请参阅partmaps.org/era/unix/award.html)。只需在末尾使用“
  • 我从没听说过这个奖项!是的,我有时会无缘无故地使用 cat ;我不知道为什么“cat x |”对我来说看起来比“ y" 让我的眼睛流血了:P
  • 猫奖没用!使用 perl -ne ...whatever... 文本文件
  • 根据@MattJ 的回答:perl -ne '0==$H{$_}++ or print',仅从未排序的输入中获取非唯一行。请注意,它将打印第二次出现 - 即第一次重复。
【解决方案2】:

uniq(1)

概要

uniq [选项]...[输入[输出]]

描述

从 INPUT(或标准输入)中丢弃除一行连续相同的行之外的所有行,写入 OUTPUT(或标准输出)。

或者,如果你也想删除不相邻的重复行,perl 的这个片段可以做到:

while(<>) {
    print $_ if (!$seen{$_});
    $seen{$_}=1;
}

【讨论】:

  • Perl 答案仅在您想要第一项时才有效。最后一个是不同的解决方案。
  • 对于那些不知道如何使用 Perl 的人,这就是你需要输入的全部内容: perl -pe 'print unless $seen{$_}++' [INPUT] > OUTPUT
  • @Xetuis,它们是同一行 :) 如果您确实想要最后一行,只需将看到的条目设置为行号,不要在循环中打印,然后将它们打印出来按最后的行号顺序。但我认为在这种情况下不需要这样做。
  • @reinierpost,是的,我永远记不起命令行选项来做到这一点,所以我倾向于求助于完整的脚本......
【解决方案3】:

这是一个 awk 实现,以防环境没有/允许 perl(还没有看到)! PS:如果有多个重复行,则打印重复输出。

awk '{

# Cut out the key on which duplicates are to be determined.
key = substr($0,2,14)

#If the key is not seen before, store in array,else print
if ( ! s[key] )
    s[key] = 1;
else
    print key;
}'

【讨论】:

  • 如果您只是将整行视为关键,这类似于 perl 解决方案:awk '!c[$0]++' file
【解决方案4】:

如果您有兴趣删除 相邻 重复行,请使用 uniq

如果你想删除所有个重复的行,而不仅仅是相邻的行,那就比较麻烦了。

【讨论】:

    【解决方案5】:

    这是我在这里等待答案时想到的(尽管第一个(并且被接受的)答案在大约 2 分钟内出现)。我在VIM 中使用了这个替换:

    %s/^\(.*\)\n\1$/\1/
    

    这意味着:在换行符之后查找与之前相同的行,并仅将它们替换为我们在第一行中捕获的内容。

    uniq 不过肯定更容易。

    【讨论】:

      猜你喜欢
      • 2010-11-15
      • 2023-03-10
      • 2011-11-08
      • 1970-01-01
      • 2014-06-03
      • 2012-04-05
      • 2018-01-31
      相关资源
      最近更新 更多