BASH - Найдите дубликаты в нескольких файлах

У меня есть несколько файлов в одном каталоге, каждый файл представляет пользователя и содержит IP-адреса, используемые для входа в эту учетную запись, каждый в новой строке.

Я хочу создать сценарий, который будет проверять, встречается ли один и тот же IP-адрес в нескольких файлах, и, конечно, печатать дубликаты.

Я пробовал использовать awk, но безуспешно, любая помощь приветствуется!


person Flawlesss    schedule 11.11.2016    source источник
comment
минимальный воспроизводимый пример), чтобы мы могли начать пытаться вам помочь.   -  person Ed Morton    schedule 11.11.2016
comment
Вы упоминаете совпадение одинаковых значений в разных файлах и дубликатах. Не могли бы вы уточнить, хотите ли вы только найти совпадающие значения в разных файлах или также повторяющиеся записи в одних и тех же файлах? Это были бы два разных результата.   -  person artdanil    schedule 11.11.2016
comment
Где твоя попытка?   -  person Deanie    schedule 21.05.2017
comment
Связано: Найдите дубликаты в двух файлах: stackoverflow.com/q/15470260/873282   -  person koppor    schedule 08.02.2018


Ответы (4)


Предполагая, что в одном файле нет повторяющихся IP-адресов, это должно работать для IPv4-адресов во многих версиях Bash:

#!/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 / repeat-ips.

person Jamil Said    schedule 11.11.2016

Используйте следующую команду 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
person Jay Rajput    schedule 11.11.2016
comment
Насколько я понимаю, в файле есть только один IP-адрес. Сложно ответить на вопрос, не зная формата файла, хранящего IP для пользователя. - person Jay Rajput; 11.11.2016
comment
Вы отменили свое изменение, поэтому я повторно публикую свой комментарий: если один и тот же IP-адрес указан в одном файле несколько раз, ваш сценарий напишет об этом, но OP хочет только информацию об одном и том же IP-адресе, появляющемся в разных файлах. - person chw21; 11.11.2016
comment
Да, я думал об этом. Не зная требований, это было ненужным загромождением кода. Я дам комментарий OP и сообщу нам требования, прежде чем я изменю. Есть масса вещей… например, что произойдет, если IP-адрес может быть расширен в одном месте и сжат в другом… Это должно быть сопоставлено? - person Jay Rajput; 11.11.2016

Не уверен, что правильно понимаю ваш вопрос, поэтому вот что, я думаю, вы хотите сделать:

У вас есть несколько файлов. Каждый файл относится к конкретному пользователю и регистрирует каждый 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

Наверное, это не лучшее решение.

person chw21    schedule 11.11.2016

Как насчет чего-то вроде:

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

Другими словами, разница между всеми файлами, объединенными и отсортированными, и всеми файлами, объединенными, отсортированными, а затем удаленными дубликатами.

person EvansWinner    schedule 11.11.2016