Виведіть загальні рядки (подібності) двох текстових файлів (протилежних розл.)?


21

Diff - чудовий інструмент для відображення змін між двома файлами. Але як відобразити схожість двох текстових файлів (ігноруючи відмінності)?

Тобто зразок введення:

a:
Foo Bar
X
Hello
World
42

b:
Foo Baz
Hello
World
23

Псевдо вихід (щось подібне):

@@ 2,3
=Hello World

Просто сортування обох файлів та використання comm недостатньо, тому що в цьому випадку інформація про рядки втрачається.

Відповіді:


24

Як щодо використання diff, навіть якщо ви не хочете різниці? Спробуйте це:

diff --unchanged-group-format='@@ %dn,%df 
  %<' --old-group-format='' --new-group-format='' \
  --changed-group-format='' a.txt b.txt

Ось що я отримую з вашими зразками даних:

$ cat a.txt 
Foo Bar
X
Hello
World
42
$ cat b.txt 
Foo Baz
Hello
World
23
$ diff --unchanged-group-format='@@ %dn,%df
%<' --old-group-format='' --new-group-format='' \
  --changed-group-format='' a.txt b.txt
@@ 2,3
Hello
World

2
Ви можете уникнути вставки буквального нового рядка таким чином:...%df'$'\n''%<'...
Призупинено до подальшого повідомлення.

1
Ви також можете зробити це так: ... --unchanged-group-format="@@ %dn,%df%c'\012'%<" ...(Зверніть увагу на подвійні лапки.)
Призупинено до подальшого повідомлення.

Чудові речі! Я не знав цих варіантів, тому що я просто переглянув сторінку
розрізненої

Я використовую diff - перетворення diff (GNU diffutils) 2.8.1 І я отримую таку помилку: diff: конфліктні параметри стилю виводу diff: Спробуйте `diff --help 'для отримання додаткової інформації.
Суджай

Я отримував "error: diff: конфліктні параметри стилю виводу diff", тому що у мене був визначений псевдонім diff. Скористайтеся, which diffщоб побачити, чи це ваша проблема.
justinjhendrick

14
grep -Fxf file1 file2

-Fозначає збігати прості рядки (не регулярні вирази), -xозначає лише відповідність цілих рядків, -fозначає взяти "шаблони" (тобто рядки) з файлу, названого як його аргумент


3
Чи не є -fі -Fобмін?. Принаймні, в моїй grepверсії так. Мені потрібно надати file2вхід до -fаргументу, як cat file1 | grep -Fxf file2, а потім працює.
Бірей

Це для мене не працює.
Чамінда Бандара

7

commможе бути використаний. man commдля всіх варіантів, але ви хочете використовувати comm -12 ...для показу лише рядки, які існують на обох входах.

Як зазначали люди, вам потрібно передати свій внесок sortспочатку.


1
Гм, це працює лише для загальних рядків, які знаходяться в одному і тому ж номері рядка в обох файлах.
maxschlepzig

2
comm, здається, призначені лише для відсортованих файлів, а не для того, щоб видавати корисний висновок для використання в ОП. Його приклад: $ comm -12 ab Hello World comm: файл 1 не впорядкованому порядку comm: файл 2 не в упорядкованому порядку
Marcel Stimberg

@maxschlepzig: слід відсортувати свої файли, перш ніж передавати їх у комунікацію.
Хемант

2
Сортуючи, ви позбудетесь усієї інформації про положення загальних ліній. Ви також не сортуватимете файли, перш ніж порівнювати їх із diff.
Марсель Стімберг

7

Я не думаю, що існує одна команда, яка робить те, що ти хочеш. Ви можете спробувати комбінувати результат diffз grep, хоча. Якщо текстові файли не містять ні один із символів |, <, >такі дає кілька корисного висновок:

$ diff --side-by-side a b | grep -n -v "[|<>]"
3:Hello                             Hello
4:World                             World

Спробуйте це:diff --width=155 --left-column --side-by-side a b | grep -n -v '|' | sed 's/ *($//'
Призупинено до подальшого повідомлення.

це виглядає краще - але вам потрібно включити <і> в grep, щоб також позбутися доданих рядків у будь-якому файлі.
Марсель Стімберг

2

Дік Грюн написав сімейство інструментів для подібних речей:

http://dickgrune.com/Programs/s подобниity_tester/

Існують версії, які аналізують синтаксис різних мов, так що такі речі, як перейменовані змінні, можна розглядати як незмінні.

Він упакований як similarity-testerу Debian та Ubuntu.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.