У меня есть два файла CSV, с которыми я работаю. Каждый является крупным приблизительно с 200 000 строк. Другой намного меньше, имея приблизительно 12 000 строк. Оба соответствуют тому же формату имен и адресам электронной почты (все законно здесь, никакие заботы). В основном я пытаюсь получить только подмножество второго списка путем удаления всех значений, которые в настоящее время существуют в большем файле.
Так, Список A имеет ~200k строки, и Список B имеет ~12k. Эти списки накладываются немного, и я хотел бы удалить все записи из Списка B, если они также существуют в Списке A, оставляя меня с новыми и уникальными значениями только в Списке B. У меня есть несколько инструментов в моем распоряжении, что я могу использовать. Откройте Office загружается на этой машине, наряду с MySQL (запросы в порядке).
Что самый легкий путь состоит в том, чтобы создать треть CSV с пересечением данных?
От командной строки Linux/Unix/Mac:
sort file1 file2 | uniq -d | sort file2 - | uniq -u
Это возвращает только те строки в file2, которые точно не соответствуют никакой строке в file1.
sort file1 file2
: Связывает file1 и file2 вместе, сортирует их и печатает их к stdout. Обратите внимание, что дубликаты будут перечислены в смежных строках (дважды подряд) после сортировки.uniq -d
: Берет вывод предыдущей команды и печатает только строки, которые являются дубликатами.sort file2 -
: Связывает оригинал file2 и вывод предыдущей команды (stdout, который представлен именем файла"-
"дефис), и печать результат к stdout. Кроме того, любые объекты в file2, которые были также в file1, будут дублированы (перечисленный дважды подряд) в выводе.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 секунд для выполнения.
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 существует собственный порт соединения.