【问题标题】:BASH - Find duplicates in multiple filesBASH - 在多个文件中查找重复项
【发布时间】:2016-11-11 00:29:59
【问题描述】:

我在同一个目录中有多个文件,每个文件代表一个用户,并包含用于登录此帐户的 IP,每个文件都在一个新行中。

我想创建一个脚本来检查相同的 IP 是否出现在多个文件中,当然还会打印重复项。

我尝试使用 awk,但没有成功,感谢任何帮助!

【问题讨论】:

  • edit 您的问题将展示简洁、可测试的样本输入和预期输出以及您迄今为止尝试过的内容(即minimal reproducible example),以便我们开始尝试帮助您。
  • 您提到在不同文件和重复文件中匹配相同的值。您能否澄清一下您是只想在不同文件中查找匹配值还是在同一文件中查找重复条目?这将是两个不同的结果。
  • 你的尝试在哪里?
  • 相关:在两个文件中查找重复项:stackoverflow.com/q/15470260/873282

标签: bash awk grep uniq


【解决方案1】:

假设同一个文件中没有重复的 IP 地址,这应该适用于许多 Bash 版本中的 IPv4 地址:

#!/bin/bash
#For IP addresses v4, assuming no repeated IP addresses on the same file; result is stored on the file /tmp/repeated-ips
mkdir -p /tmp
grep -rhEo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /home/user/folder > /tmp/ipaddresses-holder
sort /tmp/ipaddresses-holder | uniq -d > /tmp/repeated-ips
Exit 0

下面的脚本稍微复杂一些,但无论单个文件是否有重复的 IP 地址,它都可以工作:

#!/bin/bash
#For IP addresses v4, result is stored on the file /tmp/repeated-ips
mkdir -p /tmp
grep -rEo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /home/user/folder > /tmp/ipaddresses-holder
sort -u /tmp/ipaddresses-holder  > /tmp/ipaddresses-holder2
grep -rhEo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /tmp/ipaddresses-holder2 > /tmp/ipaddresses-holder3
sort /tmp/ipaddresses-holder3 | uniq -d > /tmp/repeated-ips
Exit 0

在这两种情况下,结果都存储在 /tmp/repeated-ips 文件中

【讨论】:

    【解决方案2】:

    使用以下 awk 命令:

    awk '$0 in a {print FILENAME, "IP:", $0, "also in:", a[$0]; next} {a[$0] = FILENAME}' /tmp/user*
    

    假设你有这样的IP文件

    [tmp]$cat /tmp/user1
    1.1.1.1
    [tmp]$cat /tmp/user2
    2.2.2.2
    [tmp]$cat /tmp/user3
    1.1.1.1
    

    输出

    [tmp]$awk '$0 in a {print FILENAME, "IP:", $0, "also in:", a[$0]; next} {a[$0] = FILENAME}' /tmp/user*
    /tmp/user3 IP: 1.1.1.1 also in: /tmp/user1
    

    说明

    awk '
      $0 in a {                        # if IP already exists in array a
        print FILENAME, "IP:", $0, \   # print the output
           "also in:", a[$0];
        next;                          # get the next record without further
      }                                # processing
      {a[$0] = FILENAME}               # if reached here, then we are seeing IP
    '                                  # for the first time, so store it
    

    【讨论】:

    • 我的理解是文件里只有一个IP。在不知道为用户存储 IP 的文件格式的情况下回答问题很棘手
    • 您已恢复您的更改,所以我重新发布我的评论:如果同一个 IP 多次列在同一个文件中,您的脚本将对此进行写入,但 OP 只需要关于相同的 IP 出现在不同的文件中。
    • 是的,我想过。在不了解需求的情况下,没有必要弄乱代码。在我更改之前,我会让 OP 发表评论并让我们知道要求。有很多事情......比如如果 IP 可以在一个地方扩展并在另一个地方压缩会发生什么......应该匹配吗?
    【解决方案3】:

    不确定我是否正确理解了您的问题,所以我认为您想要这样做:

    您有多个文件。每个文件都指向一个特定的用户,并记录该用户用于登录的每个 IP 地址。示例:

    $ cat alice.txt
    192.168.1.1
    192.168.1.5
    192.168.1.1
    192.168.1.1
    $ cat bob.txt
    192.168.0.1
    192.168.1.3
    192.168.1.2
    192.168.1.3
    $ cat eve.txt
    192.168.1.7
    192.168.1.5
    192.168.1.7
    192.168.0.7
    

    你想知道同一个IP地址是否出现在多个文件中。

    这是我想出的。

    #!/usr/bin/env bash
    SEARCH_TERMS="search_terms.txt"
    for source_file in $@
    do
        for search_term in $(sort -u $source_file)
        do
            found=$(grep -F "${search_term}" $@ --exclude=${source_file})
            if [[ -n "${found}" ]]; then
                echo "Found ${search_term} from ${source_file} also here:"
                echo ${found}
            fi
        done
    done
    

    这可能不是最好的解决方案。

    【讨论】:

      【解决方案4】:

      怎么样:

      diff -u <(cat * | sort) <(cat * | sort | uniq)
      

      也就是说,所有文件串联排序后,与所有文件串联排序,然后删除重复项之间的区别。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-02
        • 1970-01-01
        • 2023-01-13
        • 1970-01-01
        • 2018-03-11
        相关资源
        最近更新 更多