У меня есть два плоских файла A и B. A — большой файл с миллионами записей, а B должен быть подмножеством A. A имеет 20 столбцов с одним уникальным ключом, а B имеет 5 столбцов с тем же уникальным ключом. Не могли бы вы рассказать мне, как сравнить B с A и выяснить, присутствуют ли записи, присутствующие в файле B, также в файле A и имеют ли они те же данные в соответствующих столбцах.
решение1
Я создал два файла для демонстрации своих команд.
file1
:
1 a1 b1 c1 d1 e1
2 a2 b2 c2 d2 e2
3 a3 b3 c3 d3 e3
4 a4 b4 c4 d4 e4
5 a5 b5 c5 d5 e5
file2
:
2 b2 c2 e2
4 b4 c4 xx
5 b5 c5 e5
Первый столбец — уникальный ключ. Общие столбцы — столбец b
, c
и e
. Общие строки — 2
, 4
и 5
. Строка 4
имеет другое значение в столбце e
.
Вот команда с выводом:
$ comm -1 -3 <(cut -d' ' -f1,3,4,6 file1) file2
4 b4 c4 xx
Если файлы еще не отсортированы, то это можно сделать следующим образом:
$ comm -1 -3 <(cut -d' ' -f1,3,4,6 file1 | sort) <(sort file2)
Объяснение:
cut -d' ' -f1,3,4,6 file1
Распечатать поля номер 1, 3, 4 и 6 из файла. Поля разделены пробелом. Если поля разделены запятыми, то используйте cut
так:cut -d','
<( ... )
comm -1 -3 file1 file2
Вывести строки, уникальные для файла file2.
Предостережения:
cut
возникнут проблемы, если символ-разделитель может встречаться в поле как символ.
Например:
"field1","field2,stillfield2","field3"
cut
не поймет, что запятая "field2,stillfield2"
является частью поля.
Если ваши файлы такие, то, возможно, лучше использовать язык программирования со встроенной обработкой csv. Напримерпитон.
решение2
Если файлы содержат разные столбцы, как вы говорите, то проще всего будет написать небольшую программу на языке по вашему выбору. diff
И comm
это не принесет особой пользы, если структура строк в файлах не идентична.
решение3
Помимо comm
и diff
решения, которое вы могли бы использовать grep
для этого.
Предполагая, что ваши соответствующие данные — это столбцы 1,3 и 10 в файле A и 1,2 и 3 в файле B. Мы используем cut
для выбора столбцов из A, используем это как файл соответствия ключевых слов и обратную проверку их наличия в файле B. Если файл B содержит строку, отсутствующую в соответствующих строках, извлеченных из файла A, они будут отображены. Если все совпадают, вывода нет (так как B предположительно является подмножеством A)
grep -wvf <( cut -f1,3,10 fileA ) fileB
Или если файл B содержит больше трех столбцов:
grep -wvf <( cut -f1,3,10 fileA ) <( cut -f1,2,3 fileB )