сравнение 2 больших несортированных файлов CSV на основе 2 столбцов

1

Я работаю с сопоставлением 2 больших несортированных .csv файлов на основе столбцов 1 и 3. Каждый файл содержит около 200 тыс. Записей. Для вывода мне нужно знать, какие записи на основе столбцов 1 и 3 существуют в первом файле, но не во втором файле. Файлы представляют собой данные с разделителями-запятыми. Столбец 3 должен игнорировать случай при сравнении.

Пример файла1:

"id", "name", "email", "country"
"1233",  "jake", "[email protected]", "USA"
"2345", "alison", "[email protected]", "Canada"
"3456", "jacob", "[email protected]", "USA"
"5678", "natalia", "[email protected]", "USA"

Файл 2

"id", "name", "email", "country"
"2345", "alison", "[email protected]", "Canada"
"3456", "jacob", "[email protected]", "USA"
"5690", "lina", "[email protected]", "Canada" 

желаемый выходной файл

"5678", "natalia", "[email protected]", "USA"

Примеры кода были бы очень оценены.

  • 0
    На каком языке и что вы уже сделали и в чем проблема?
  • 0
    Почему строка "1233", "jake", "[email protected]" "USA" не отображается в выводе?
Показать ещё 2 комментария
Теги:
csv
awk

5 ответов

1
Лучший ответ

Пытаться:

join -v 1 -i -t, -1 1 -2 1 -o 1.2 1.3 1.4 1.5  <(awk -F, '{print $1":"$3","$0}' f1.txt | sort) <(awk -F, '{print $1":"$3","$0}' f2.txt | sort)

Как это работает:

1) Сначала я создаю колонку составного ключа, соединяя столбцы 1 и столбец 3:

awk -F, '{print $1":"$3","$0}' f1.txt
awk -F, '{print $1":"$3","$0}' f2.txt

2) Я сортирую оба выхода:

awk -F, '{print $1":"$3","$0}' f1.txt | sort 
awk -F, '{print $1":"$3","$0}' f2.txt | sort 

3) Затем я использую команду join чтобы присоединиться к первому столбцу (мой составной ключ) и выводить неоплачиваемые строки, исходящие из файла 1.

Вывод:

"1233",  "jake", "[email protected]", "USA"
"5678", "natalia", "[email protected]", "USA"
  • 0
    +1 столбец 3 считается нечувствительным к регистру, поэтому вместо него просто нужно tolower($3) .
  • 1
    @ glenn-jackman Я использую join -i чтобы игнорировать регистр.
Показать ещё 1 комментарий
0
awk 'BEGIN { FS=OFS=","}; NR==FNR{a[tolower($1$3)]=++i;next} { if ( tolower($1$3) in a);else {print } }' file2 file1

вывод:

"1233",  "jake", "[email protected]", "USA"
"5678", "natalia", "[email protected]", "USA"
0

Загрузите содержимое файла в базу данных памяти, например H2, и используйте выбор SQL с соединением

0

Скопируйте файлы, загрузите их в 2 массива (или, возможно, хэши), затем зациклируйте второй файл, массив каждой строки. Если array1[n] и array2[n] не находятся в текущем массиве строк, выведите их как отсутствующие. Я бы использовал Perl для этой задачи.

  • 0
    Файлы большие. Возможно, не стоит загружать их в массивы.
  • 0
    Затем для каждой строки в базовом файле ищите построчно во втором файле. Не так быстро, но вы не столкнетесь с проблемами памяти.
0
awk 'BEGIN { FS="\", \""}
     FNR == 1 {read++;}
     FNR !=1 {if (read==1) {store[$1","tolower($3)] = $0} if (read==2) {delete store[$1","tolower($3)]}}
     END {for (i in store) {print store[i]}}' file1 file2

Вывод:

"1233",  "jake", "[email protected]", "USA"
"5678", "natalia", "[email protected]", "USA"

Ещё вопросы

Сообщество Overcoder
Наверх
Меню