отображать записи, которые существуют в файле2, но отсутствуют в файле1 - PullRequest
0 голосов
/ 16 марта 2010

log file1 содержит записи клиентов (имя, идентификатор, дата), которые посетили вчера log file2 содержит записи клиентов (имя, идентификатор, дата), которые посетили сегодня

Как бы вы отобразили клиентов, которые посетили вчера, но не сегодня?

Ограничение: не используйте вспомогательную структуру данных, потому что файл содержит миллионы записей. [Итак, без хэшей] Есть ли способ сделать это с помощью команд Unix ??

Ответы [ 3 ]

2 голосов
/ 17 марта 2010

пример, но проверьте справочную страницу comm для выбора нужной опции.

comm -2 <(sort -u yesterday) <(sort -u today)

Другой инструмент, который вы можете использовать: diff

diff <(sort -u yesterday) <(sort -u today)
0 голосов
/ 16 марта 2010

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

В псевдокоде это выглядит как python, но может быть переписано в perl или shell-скрипте или ...

import subprocess 
import os

for line in fileinput.input(['myfile'])::
    # split out data. For the sake of it I'm assuming name\tid\tdate
    fields = line.split("\")
    id = fields[1]

    grepresult = subprocess.Popen("grep \"" + id + "\" file1", shell=True, bufsize=bufsize, stdout=PIPE).stdout

    if len(grepresult) == 0:
        print fields # it wasn't in field1

Это не идеально, не проверено, так что относитесь соответствующим образом, но это дает вам представление о том, как вы будете использовать команды Unix. Тем не менее, как указывает sfussenegger, C / C ++, если вы используете именно это, должны быть в состоянии обрабатывать довольно большие файлы.

Отказ от ответственности: это не очень аккуратное решение (неоднократно вызывающее grep), чтобы соответствовать требованиям вопроса. Если бы я делал это, я бы использовал C.

0 голосов
/ 16 марта 2010

Идентифицирован ли клиент по идентификатору? Это int или long? Если ответ на оба вопроса - да, массив с 10 000 000 целых чисел не должен занимать более 10 МБ * 4 = 40 МБ памяти - не так уж и много на достойном оборудовании Просто отсортируйте и сравните их.

Кстати, сортировка массива с 10M случайными числами занимает на моей машине менее 2 секунд - опять же, нечего бояться.

Вот очень простой Java-код:

public static void main(final String args[]) throws Exception {

    // elements in each log file
    int count = 10000000;

    // "read" our log file
    Random r = new Random();
    int[] a1 = new int[count];
    int[] a2 = new int[count];
    for (int i = 0; i < count; i++) {
        a1[i] = Math.abs(r.nextInt());
        a2[i] = Math.abs(r.nextInt());
    }

    // start timer
    long start = System.currentTimeMillis();

    // sort logs
    Arrays.sort(a1);
    Arrays.sort(a2);

    // counters for each array
    int i1 = 0, i2 = 0, i3 = 0;

    // initial values
    int n1 = a1[0], n2 = a2[0];

    // result array
    int[] a3 = new int[count];

    try {
        while (true) {
            if (n1 == n2) {
                // we found a match, save value if unique and increment counters
                if (i3 == 0 || a3[i3-1] != n1) a3[i3++] = n1;
                n1 = a1[i1++];
                n2 = a2[i2++];
            } else if (n1 < n2) {
                // n1 is lower, increment counter (next value is higher)
                n1 = a1[i1++];
            } else {
                // n2 is lower, increment counter (next value is higher)
                n2 = a2[i2++];
            }
        }
    } catch (ArrayIndexOutOfBoundsException e) {
        // don't try this at home - it's not the pretties way to leave the loop!
    }

    // we found our results
    System.out.println(i3 + " commont clients");
    System.out.println((System.currentTimeMillis() - start) + "ms");

}

результат

// sample output on my machine:
46308 commont clients
3643ms

как видите, достаточно эффективно для 10M записей в каждом журнале

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...