Як порівняти два текстові файли в терміналі Linux

Потрібно побачити відмінності між двома версіями текстового файлу? Тоді diff – це команда, яка вам потрібна. У цьому підручнику показано, як використовувати diff у Linux та macOS, простий спосіб.

Занурення в диф

Команда diff порівнює два файли та створює список відмінностей між ними. Щоб бути більш точним, він створює список змін, які потрібно внести до першого файлу, щоб він відповідав другому файлу. Якщо ви матимете це на увазі, вам буде легше зрозуміти вихід із diff. Команда diff була розроблена, щоб знайти відмінності між файлами вихідного коду та створити вихід, який можна було б читати та виконувати інші програми, наприклад, патч команда. У цьому підручнику ми розглянемо найкорисніші зручні для людини способи використання diff.

Давайте зануримося і проаналізуємо два файли. Порядок файлів у командному рядку визначає, який файл diff вважатиме «першим файлом», а який — «другим файлом». У наведеному нижче прикладі alpha1 — це перший файл, а alpha2 — другий файл. Обидва файли містять файл фонетичний алфавіт але другий файл, alpha2, зазнав подальшого редагування, щоб два файли не були ідентичними.

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

diff alpha1 alpha2

Як ми розібрати цей вихід? Коли ви знаєте, на що шукати, це не так вже й погано. Кожна різниця перераховується по черзі в одному стовпці, і кожна відмінність позначається. Мітка містить цифри по обидва боки від літери, наприклад 4c4. Перше число – це номер рядка в альфа-1, а друге – номер рядка в альфа-2. Буква в середині може бути:

c: рядок у першому файлі потрібно змінити, щоб він відповідав рядку у другому файлі.
d: рядок у першому файлі потрібно видалити, щоб відповідати другому файлу.
a: до першого файлу необхідно додати додатковий вміст, щоб він відповідав другому файлу.

4c4 в нашому прикладі говорить нам, що четвертий рядок alpha1 потрібно змінити, щоб відповідати четвертому рядку alpha2. Це перша відмінність між двома файлами, які знайдено diff.

Рядки, які починаються з, посилаються на другий файл, alpha2. Рядок Dave говорить нам, що слово Dave є вмістом четвертого рядка в alpha2. Підводячи підсумок, нам потрібно замінити Delta на Dave в четвертому рядку в alpha1, щоб цей рядок збігався в обох файлах.

Наступна зміна позначається 12c12. Застосовуючи ту ж логіку, це говорить нам, що рядок 12 в alpha1 містить слово Lima, але рядок 12 в alpha2 містить слово Linux.

Третя зміна відноситься до рядка, який був видалений з alpha2. Мітка 21d20 розшифровується як «рядок 21 потрібно видалити з першого файлу, щоб обидва файли синхронізувалися з рядка 20». The

Четверта різниця позначена 26a26,28. Ця зміна стосується трьох додаткових рядків, які були додані до alpha2. Зверніть увагу на 26,28 на етикетці. Дворядкові числа, розділені комою, представляють діапазон номерів рядків. У цьому прикладі діапазон — від рядка 26 до рядка 28. Мітка інтерпретується як «у рядку 26 у першому файлі додайте рядки з 26 по 28 з другого файлу». Нам показано три рядки в alpha2, які потрібно додати до alpha1. Вони містять слова “Чудний”, “Дивний” і “Чарівність”.

Snappy One-Lines

Якщо ви хочете знати лише те, чи є два файли однаковими, використовуйте параметр -s (повідомити про ідентичні файли).

diff -s alpha1 alpha3

Ви можете використовувати параметр -q (короткий), щоб отримати однаково стислий вислів про те, що два файли є різними.

diff -q alpha1 alpha2

Варто звернути увагу на те, що з двома однаковими файлами параметр-q (короткий) повністю замикається і взагалі нічого не повідомляє.

Альтернативний погляд

Параметр -y (пліч-о-пліч) використовує інший макет для опису відмінностей файлів. Часто зручно використовувати параметр -W (ширина) з боковим виглядом, щоб обмежити кількість стовпців, які відображаються. Це дозволяє уникнути некрасивих рядків, які ускладнюють читання результатів. Тут ми сказали diff створювати супутнє відображення та обмежити вихід до 70 стовпців.

diff -y -W 70 alpha1 alpha2

Перший файл у командному рядку, alpha1, показаний ліворуч, а другий рядок командного рядка, alpha2, показаний праворуч. Рядки з кожного файлу відображаються поруч. Поруч із тими рядками в альфа-2, які були змінені, видалені або додані, є символи-індикатори.

|: рядок, який було змінено в другому файлі.
<: a="" line="" that="" has="" been="" deleted="" from="" the="" second="" file.="">: рядок, доданий до другого файлу, якого немає в першому файлі.

Якщо ви віддаєте перевагу компактнішому пліч-о-пліч зведенню відмінностей файлів, використовуйте параметр –suppress-common-lines. Це змушує diff відображати лише змінені, додані чи видалені рядки.

diff -y -W 70 --suppress-common-lines alpha1 alpha2

Додайте сплеск кольору

Інша утиліта, яка називається colordiff, додає підсвічування кольором до вихідних даних diff. Завдяки цьому набагато легше побачити, які лінії мають відмінності.

Використовуйте apt-get, щоб встановити цей пакунок у вашу систему, якщо ви використовуєте Ubuntu або інший дистрибутив на базі Debian. В інших дистрибутивах Linux замість цього використовуйте інструмент керування пакетами свого дистрибутива Linux.

sudo apt-get install colordiff

Використовуйте colordiff так само, як і diff.

Насправді, colordiff — це обгортка для diff, і diff виконує всю роботу за кадром. Через це всі параметри diff працюватимуть з colordiff.

Надання певного контексту

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

Перший метод використовує параметр -c (скопійований контекст).

colordiff -c alpha1 alpha2

Вихід diff має заголовок. У заголовку вказані два назви файлів і час їх модифікації. Є зірочки

перед назвою першого файлу та тире (-) перед назвою другого файлу. Зірочки та тире будуть використовуватися, щоб вказати, до якого файлу належать рядки у виводі.

Лінія зірочок із 1,7 посередині вказує на те, що ми дивимося на лінії від alpha1. Якщо бути точним, ми розглядаємо рядки з першого по сім. Слово Delta позначено як змінене. Поруч із ним є знак оклику (!), він червоний. Перед і після цього рядка відображаються три рядки незмінного тексту, щоб ми могли побачити контекст цього рядка у файлі.

Лінія тире з 1,7 посередині говорить нам, що ми зараз дивимося на лінії від alpha2. Знову ми дивимося на рядки з першого по сьомий, зі словом Дейв у четвертому рядку позначено як інше.

colordiff -C 2 alpha1 alpha2

Три рядки контексту над і під кожною зміною є значенням за замовчуванням. Ви можете вказати, скільки рядків контексту ви хочете надати diff. Для цього скористайтеся параметром -C (скопійований контекст) з великої букви «C» і вкажіть потрібну кількість рядків:

colordiff -u alpha1 alpha2

Другим параметром diff, який пропонує контекст, є параметр -u (уніфікований контекст).

Як і раніше, у нас на виході є заголовок. Два файли мають імена та показують час їх модифікації. Перед назвою alpha1 є тире (-), а перед назвою alpha2 — знаки плюс (+). Це говорить нам, що для позначення alpha1 використовуватимуться тире, а для позначення alpha2 — знаки плюс. По всьому списку розкидані рядки, які починаються зі знаків (@). Ці рядки позначають початок кожної різниці. Вони також повідомляють нам, які рядки відображаються з кожного файлу.

Нам показують три рядки до і після рядка, позначені як різні, щоб ми могли бачити контекст зміненого рядка. В уніфікованому вигляді лінії з різницею показані одна над одною. Рядку від alpha1 передує тире, а рядку від alpha2 передує знак плюс. Цей дисплей у восьми рядках отримує те, що для скопійованого вище контекстного дисплея знадобилося п’ятнадцять.

colordiff -U 2 alpha1 alpha2

Як і слід було очікувати, ми можемо попросити diff надати саме ту кількість рядків уніфікованого контексту, яку ми хотіли б бачити. Для цього скористайтеся параметром -U (уніфікований контекст) з великої букви «U» та вкажіть потрібну кількість рядків:

Ігнорування пробілів і регістру

colordiff -y -W 70 test4 test5

Давайте розберемо ще два файли, test4 і test5. У них є шість імен супергероїв.

Результати показують, що diff не знаходить нічого іншого з лініями Чорної Вдови, Людини-павука та Тора. Він відзначає зміни з лініями Капітана Америки, Залізного людини та Халка.

Отже, чим відрізняється? Ну, у test5 Халк пишеться з малої букви «h», а Капітан Америка має додатковий пробіл між «Капітан» та «Америка». Добре, це зрозуміло, але що не так з лінією Ironman? Видимих ​​відмінностей немає. Ось гарне правило. Якщо ви не бачите його, відповідь – пробіл. Майже напевно в кінці цього рядка є один або два пробіли або символ табуляції.

Якщо вони для вас не мають значення, ви можете вказати diff ігнорувати певні типи різниці рядків, зокрема:
-i: Ігноруйте відмінності у регістрі.
-Z: Ігнорувати кінцевий пробіл.
-b: ігнорувати зміни в кількості пробілів.

-w: ігнорувати всі зміни пробілів.

colordiff -i -y -W 70 test4 test5

Давайте попросимо diff ще раз перевірити ці два файли, але цього разу ігнорувати будь-які відмінності.

colordiff -i -Z -y -W 70 test4 test5

Рядки з «Халк» і «Халк» тепер вважаються збіговими, і для малої «h» різниця не позначається. Давайте попросимо diff також ігнорувати кінцевий пробіл.

colordiff -i -w -y -W 70 test4 test5

Як підозрювалося, різниця в рядку Ironman, напевно, була кінцевим пробілом, оскільки diff більше не позначає різницю для цього рядка. Залишається Капітан Америка. Давайте попросимо diff ігнорувати регістр і ігнорувати всі проблеми з пробілами.

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

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