Как показать линии в общем (обратный diff)? - PullRequest
159 голосов
/ 14 апреля 2009

У меня есть ряд текстовых файлов, для которых я хотел бы знать общие линии, а не строки, которые отличаются между ними. Командная строка Unix или Windows в порядке.

Foo:

linux-vdso.so.1 =>  (0x00007fffccffe000)
libvlc.so.2 => /usr/lib/libvlc.so.2 (0x00007f0dc4b0b000)
libvlccore.so.0 => /usr/lib/libvlccore.so.0 (0x00007f0dc483f000)
libc.so.6 => /lib/libc.so.6 (0x00007f0dc44cd000)

бар

libkdeui.so.5 => /usr/lib/libkdeui.so.5 (0x00007f716ae22000)
libkio.so.5 => /usr/lib/libkio.so.5 (0x00007f716a96d000)
linux-vdso.so.1 =>  (0x00007fffccffe000)

Итак, учитывая, что эти два файла выше вывода желаемой утилиты были бы похожи на file1:line_number, file2:line_number == matching text (просто предложение, мне действительно все равно, какой синтаксис):

foo:1, bar:3 == linux-vdso.so.1 =>  (0x00007fffccffe000)

спасибо.

Ответы [ 6 ]

191 голосов
/ 14 апреля 2009

На * nix вы можете использовать comm . Ответ на вопрос:

comm -1 -2 file1.sorted file2.sorted 
# where file1 and file2 are sorted and piped into *.sorted

Вот полное использование comm:

comm [-1] [-2] [-3 ] file1 file2
-1 Suppress the output column of lines unique to file1.
-2 Suppress the output column of lines unique to file2.
-3 Suppress the output column of lines duplicated in file1 and file2. 

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

46 голосов
/ 15 января 2015

Нашли этот ответ на вопрос, указанный как дубликат . Я нахожу, что grep более удобен для администратора, чем comm, поэтому, если вы просто хотите, чтобы набор совпадающих строк (например, полезный для сравнения CSV) просто использовал

grep -F -x -f file1 file2

или упрощенная версия fgrep

fgrep -xf file1 file2

Кроме того, вы можете использовать file2* для поиска и поиска строк, общих для нескольких файлов, а не только для двух.

Некоторые другие удобные варианты включают

  • -n флаг для отображения номера строки каждой совпавшей строки
  • -c только для подсчета количества совпадающих строк
  • -v для отображения только строк в файле2 , которые отличаются (или используют diff).

Использование comm быстрее, но эта скорость достигается за счет необходимости сначала сортировать файлы. Это не очень полезно в качестве «обратного дифференциала».

33 голосов
/ 14 апреля 2009

Здесь уже спрашивали: Команда Unix для поиска общих строк в двух файлах

Вы также можете попробовать с Perl (кредит здесь )

perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/'  file1 file2
16 голосов
/ 08 сентября 2014

Я только что узнал команду comm из этого потока, но хотел добавить что-то дополнительное: если файлы не отсортированы, и вы не хотите трогать исходные файлы, вы можете передать результат команды sort. Это оставляет исходные файлы без изменений. Работает в bash, я не могу сказать о других оболочках.

comm -1 -2 <(sort file1) <(sort file2)

Это может быть расширено для сравнения выходных данных команды вместо файлов:

comm -1 -2 <(ls /dir1 | sort) <(ls /dir2 | sort)
5 голосов
/ 28 апреля 2017

Самый простой способ сделать это:

awk 'NR==FNR{a[$1]++;next} a[$1] ' file1 file2

Файлы не нужно сортировать.

1 голос
/ 12 февраля 2015

Просто для информации, я сделал небольшой инструмент для Windows, делающий то же самое, что и "grep -F -x -f file1 file2" (поскольку я не нашел ничего эквивалентного этой команде в Windows)

Вот оно: http://www.nerdzcore.com/?page=commonlines

Использование: «CommonLines inputFile1 inputFile2 outputFile»

Исходный код также доступен (GPL)

...