Ответ 1
Союз: sort -u
файлы...
Пересечение: sort
файлы... | uniq -d
Разница: sort
файлы... | uniq -u
Мне иногда приходится сравнивать два текстовых файла. Очевидно, что 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
Союз: sort -u
файлы...
Пересечение: sort
файлы... | uniq -d
Разница: sort
файлы... | uniq -u
Если вы хотите получить общие строки между двумя файлами, вы можете использовать утилиту comm.
A.txt:
A
B
C
b.txt
A
B
D
а затем, используя comm, вы получите:
$ comm <(sort A.txt) <(sort B.txt)
A
B
C
D
В первом столбце у вас есть то, что находится в первом файле, а не во втором.
Во втором столбце у вас есть то, что находится во втором файле, а не в первом.
В третьем столбце у вас есть то, что находится в обоих файлах.
Если вы не против использовать немного 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($_);
}
Я не могу комментировать ответ Аарона Дигуллы, который, несмотря на то, что он принят, фактически не вычисляет значение .
Установленная разность A\B с данными входами должна возвращать только mary
, но принятый ответ также неверно возвращает adam
.
Этот ответ имеет однострочный awk, который правильно вычисляет разницу между наборами:
awk 'FNR==NR {a[$0]++; next} !a[$0]' b.txt a.txt