Получение поперечного сечения из двух файлов CSV

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

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

Что самый легкий путь состоит в том, чтобы создать треть CSV с пересечением данных?

1
задан 17.05.2010, 21:24

2 ответа

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

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

Объяснение:

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

Шаги:

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

Возможные глюки:

Это предполагает, что любая данная строка в file1 точно соответствует соответствующей строке в file2. Если, например, file1 и file2 имел ту же электронную почту, но с другой капитализацией; или если бы file1 имел имя как "Jon Sampson", в то время как file2 имел тот же адрес электронной почты с именем "Jonathan Sampson", их не считали бы дубликатами.

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

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

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

4
ответ дан 12.12.2019, 08:16

Nate дал Вам действительно хороший ответ, но от командной строки 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 существует собственный порт соединения.

2
ответ дан 12.12.2019, 08:16

Теги

Похожие вопросы