【问题标题】:Remove non duplicated lines in text file删除文本文件中不重复的行
【发布时间】:2014-10-30 22:27:57
【问题描述】:

我有一长串 100k+ 的 IP 地址在某个范围内,这个脚本的一个例子是:

67.0.105.76 0
67.0.123.150 0
67.0.123.150 0
67.0.123.150 0
67.0.123.150 0
67.0.123.150 0
67.0.123.150 0
67.0.123.150 0
67.0.123.150 0
67.0.105.76 0
67.0.123.150 0
67.0.163.127 0
67.0.123.150 0
67.0.163.127 0
67.0.163.127 0
67.0.163.127 0
67.0.163.127 0
67.0.163.127 0
67.0.163.127 0
67.0.163.127 0
67.0.163.127 0
67.0.163.127 0
67.0.105.76 0
67.0.105.76 0
67.0.105.76 0
67.0.232.158 0
67.0.232.158 0
67.0.232.158 0
67.0.232.158 0
67.0.232.158 0
67.0.232.158 0
67.0.232.158 0
67.0.232.158 0
67.0.232.158 0
67.0.232.158 0
67.0.105.76 0
67.0.143.13 0

我想从这个列表中删除任何未多次列出的 IP,因此假设我想从上面的列表中删除所有未列出 5 次或更多次的 IP。然后它会输出:

67.0.105.76 0
67.0.123.150 0
67.0.163.127 0
67.0.232.158 0

我尝试在 Linux 中使用 sed/uniq 来完成此操作,但无法找到一种方法来执行此操作,是否需要 python 脚本或类似的方法,或者是否有可能使用 sed/uniq 的方法?

使用 sort -u 100kfile,它能够删除所有重复项,但仍然保留单个 ip。

【问题讨论】:

    标签: python linux sorting sed uniq


    【解决方案1】:

    这是awk的简单方法

    awk '{a[$0]++} END {for (i in a) if (a[i]>4) print i}' file
    67.0.232.158 0
    67.0.105.76 0
    67.0.163.127 0
    67.0.123.150 0
    

    计算每个唯一 IP 并将数字存储在数组中 a
    如果还有更多 4 命中,请打印。
    它应该比sortuniqawk更快。

    PS 我发这个后确实看到了,和 jaypal 在评论里发的一样。

    【讨论】:

      【解决方案2】:

      纯 Python 解决方案,使用来自 collections moduleCounter 工具。

      我不知道这将如何处理 100k 个地址,但你可以试一试。

      from collections import Counter
      
      with open('ip_file.txt', 'r') as f:
          ip_list     = map(lambda x: x.strip(), f.readlines())
          ip_by_count = Counter(ip_list)
      
          for ip in ip_by_count:
              if ip_by_count[ip] > 1:
                  print ip
      

      或者另一种方法:维护两组,一组 IP 只见过一次,一组 IP 至少见过两次。当我们第二次看到它时打印一个 IP,并跳过所有后续出现:

      known_dupes = set()
      single_ips  = set()
      
      with open('ip_file.txt', 'r') as f:
          ip_list = map(lambda x: x.strip(), f.readlines())
      
          for ip in ip_list:
              if ip in known_dupes:
                  continue
              elif ip in single_ips:
                  print ip
                  known_dupes.add(ip)
                  single_ips.remove(ip)
              else:
                  single_ips.add(ip)
      

      我怀疑第一个可能更快,但我还没有在大文件上尝试过检查。

      【讨论】:

        【解决方案3】:

        使用sortuniqawk

        pu@pumbair: ~  sort data.txt | uniq -c | awk '{if ($1 > 4) print $2,$3}'
        67.0.105.76 0
        67.0.123.150 0
        67.0.163.127 0
        67.0.232.158 0
        

        【讨论】:

        • 如果散落的话好像漏掉了一些,我在我的大单子上试过了,似乎还在重复一些puu.sh/bn8Kl/bc8b1d6bf7.txt
        • +1:您完全可以在awk 中完成。 awk ' { ips[$0]++ } END { for (ip in ips) if (ips[ip] >= 5) print ip }' data.txt
        猜你喜欢
        • 1970-01-01
        • 2010-11-17
        • 2018-01-31
        • 2011-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多