1

У меня есть два CSV-файла, с которыми я работаю. Один массивный, около 200 000 строк. Другой намного меньше, около 12 000 строк. Оба соответствуют одному и тому же формату имен и адресов электронной почты (здесь все законно, не беспокойтесь). В основном я пытаюсь получить только подмножество второго списка, удаляя все значения, которые в настоящее время существуют в файле большего размера.

Итак, список A имеет ~ 200 тыс. Строк, а список B - ~ 12 тыс. Эти списки немного пересекаются, и я хотел бы удалить все записи из списка B, если они также существуют в списке A, оставив мне новые и уникальные значения только в списке B. В моем распоряжении есть несколько трюков, которые я могу можешь использовать. Open Office загружается на этот компьютер вместе с MySQL (запросы в порядке).

Какой самый простой способ создать третий CSV с пересечением данных?

2 ответа2

4

Из командной строки Linux/Unix/Mac:

sort file1 file2 | uniq -d | sort file2 - | uniq -u

Объяснение:

Это возвращает только те строки в file2, которые точно не соответствуют ни одной строке в file1.

шаги:

  1. sort file1 file2: объединяет file1 и file2 вместе, сортирует их и печатает на стандартный вывод. Обратите внимание, что дубликаты будут перечислены в соседних строках (дважды подряд) после сортировки.
  2. uniq -d: принимает выходные данные предыдущей команды и печатает только строки, которые являются дубликатами.
  3. sort file2 -: объединяет исходный файл2 и выходные данные предыдущей команды (stdout, который представлен именем файла " - " дефис) и печатает результат в stdout. Кроме того, любые элементы в file2, которые также были в file1, будут продублированы (перечислены два раза подряд) в выходных данных.
  4. uniq -u: принимает выходные данные предыдущей команды и печатает только элементы, которые не дублируются (другими словами, печатает только элементы, которые не перечислены дважды подряд).

Возможные ошибки:

Это предполагает, что любая заданная строка в file1 точно соответствует соответствующей строке в file2. Если, например, file1 и file2 имели один и тот же адрес электронной почты, но с разной капитализацией; или если файл1 имеет имя "Джон Сэмпсон", а файл2 имеет тот же адрес электронной почты с именем "Джонатан Сэмпсон", они не будут считаться дубликатами.

Вы можете контролировать это, предварительно обработав файл, чтобы удалить все, кроме адреса электронной почты, и, кроме того, строчный адрес электронной почты. Команды Unix cut и tr могут быть полезны в этом случае. Или вы можете переключиться на SQL для более сложных сценариев.

Размер файла:

Файл из 200 000 строк и одна из 12 000 строк не очень большой. Я сгенерировал файлы одинакового размера, используя файл /usr/share/dict/words на моем MacBook Pro, и протестировал приведенную выше команду; Это заняло менее 5 секунд.

2

Нейт дал вам действительно хороший ответ, но есть более короткий путь из командной строки Linux/Unix/Mac:

join -t# -v2 <(sort file1.csv) <(sort file2.csv) > result.csv

Предостережения:

  • Оригинальный вопрос о соединении целых строк. Единственный способ, которым я могу думать
    Подавление join необходимость определения разделителя поля как символа, который не используется ни в одном из файлов (# в моем примере). Гадкий, я знаю.

  • Входные файлы должны быть отсортированы в поле соединения. Вы можете сделать это в одну строку (см. Выше), но это будет работать только в bash . Другие оболочки имеют другой синтаксис для этого.

Если ваши входные файлы отсортированы:

join -t# -v2 file1.csv file2.csv > result.csv

Для Windows есть собственный порт соединения.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .