Подтвердить что ты не робот

* nix: выполнить объединение/пересечение/различие списков

Мне иногда приходится сравнивать два текстовых файла. Очевидно, что diff показывает различия, а также скрывает сходства, которые являются своего рода точкой.

Предположим, что я хочу делать другие сравнения в этих файлах: установить объединение, пересечение и вычитание, рассматривая каждую строку как элемент в наборе.

Существуют ли аналогичные простые общие утилиты или однострочные, которые могут это сделать?


Примеры:

a.txt

john
mary

b.txt

adam
john

$> set_union a.txt b.txt
john
mary
adam

$> set_intersection a.txt b.txt
john

$> set_difference a.txt b.txt
mary
4b9b3361

Ответ 1

Союз: sort -u файлы...

Пересечение: sort файлы... | uniq -d

Разница: sort файлы... | uniq -u

Ответ 2

Если вы хотите получить общие строки между двумя файлами, вы можете использовать утилиту comm.

A.txt:

A
B
C

b.txt

A
B
D

а затем, используя comm, вы получите:

$ comm <(sort A.txt) <(sort B.txt)
        A
        B
C
    D

В первом столбце у вас есть то, что находится в первом файле, а не во втором.

Во втором столбце у вас есть то, что находится во втором файле, а не в первом.

В третьем столбце у вас есть то, что находится в обоих файлах.

Ответ 3

Если вы не против использовать немного Perl, и если ваши размеры файлов разумны, чтобы их можно было записать в хэш, вы могли бы собрать файлы в два хэша:

#...get common keys in an array...
my @both_things
for (keys %from_1) {
    push @both_things, $_ if exists $from_2{$_};
}

#...put unique things in an array...
my @once_only
for (keys %from_1) {
    push @once_only, $_ unless exists $from_2($_);
}

Ответ 4

Я не могу комментировать ответ Аарона Дигуллы, который, несмотря на то, что он принят, фактически не вычисляет значение .

Установленная разность A\B с данными входами должна возвращать только mary, но принятый ответ также неверно возвращает adam.

Этот ответ имеет однострочный awk, который правильно вычисляет разницу между наборами:

awk 'FNR==NR {a[$0]++; next} !a[$0]' b.txt a.txt