Как сравнить два текстовых файла в терминале Linux

Хотите увидеть разницу между двумя версиями текстового файла? Тогда вам нужна команда diff. В этом руководстве показано, как легко использовать diff в Linux и macOS.

Погружение в diff

Команда diff сравнивает два файла и выдает список различий между ними. Чтобы быть более точным, он создает список изменений, которые необходимо внести в первый файл, чтобы он соответствовал второму файлу. Если вы запомните это, вам будет легче понять вывод команды diff. Команда diff была разработана для поиска различий между файлами исходного кода и для создания вывода, который может быть прочитан и обработан другими программами, такими как патч команда. В этом руководстве мы рассмотрим наиболее удобные для человека способы использования diff.

Давайте погрузимся в анализ двух файлов. Порядок файлов в командной строке определяет, какой файл diff считает «первым файлом», а какой — «вторым файлом». В приведенном ниже примере alpha1 — это первый файл, а alpha2 — второй файл. Оба файла содержат фонетический алфавит но второй файл, alpha2, подвергся дальнейшему редактированию, так что эти два файла не идентичны.

Мы можем сравнить файлы с помощью этой команды. Введите diff, пробел, имя первого файла, пробел, имя второго файла и нажмите Enter.

diff alpha1 alpha2

Вывод команды diff без параметров

Как мы анализируем этот результат? Когда вы знаете, что искать, это не так уж и плохо. Каждое различие перечислено по очереди в одном столбце, и каждое различие помечено. Этикетка содержит числа по обе стороны от буквы, например 4c4. Первое число — это номер строки в альфа1, а второе число — это номер строки в альфа2. Буква посередине может быть:

c: строку в первом файле необходимо изменить, чтобы она соответствовала строке во втором файле.
d: строка в первом файле должна быть удалена, чтобы соответствовать второму файлу.
a: В первый файл необходимо добавить дополнительный контент, чтобы он соответствовал второму файлу.

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

Строки, начинающиеся с, относятся ко второму файлу, alpha2. Строка Дэйв сообщает нам, что слово Дэйв является содержанием четвертой строки в alpha2. Подводя итог, нам нужно заменить Delta на Dave в четвертой строке в alpha1, чтобы эта строка совпадала в обоих файлах.

  Как поделиться скриншотами Linux в Интернете с помощью ScreenCloud

Следующее изменение обозначено 12c12. Применяя ту же логику, это говорит нам, что строка 12 в alpha1 содержит слово Lima, а строка 12 alpha2 содержит слово Linux.

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

Четвертое отличие обозначено 26a26,28. Это изменение касается трех дополнительных строк, которые были добавлены в alpha2. Обратите внимание на 26,28 на этикетке. Двухстрочные номера, разделенные запятой, представляют собой диапазон номеров строк. В этом примере диапазон составляет от строки 26 до строки 28. Метка интерпретируется как «в строке 26 в первом файле добавьте строки с 26 по 28 из второго файла». Нам показаны три строки в alpha2, которые нужно добавить к alpha1. Они содержат слова Quirk, Strange и Charm.

Snappy One-Liners

Если все, что вам нужно знать, это то, являются ли два файла одинаковыми, используйте параметр -s (сообщать об идентичных файлах).

diff -s alpha1 alpha3

Вывод команды diff с параметром -s

Вы можете использовать опцию -q (кратко), чтобы получить одинаково краткое заявление о том, что два файла разные.

diff -q alpha1 alpha2

Вывод команды diff с параметром -q

Следует обратить внимание на то, что с двумя идентичными файлами опция -q (краткое) полностью закрывается и вообще ни о чем не сообщает.

Альтернативный взгляд

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

diff -y -W 70 alpha1 alpha2

Вывод команды diff с параллельным отображением

Первый файл в командной строке, alpha1, отображается слева, а вторая строка в командной строке, alpha2, отображается справа. Строки из каждого файла отображаются рядом. Рядом с теми строками в alpha2, которые были изменены, удалены или добавлены, есть символы индикатора.

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

Если вы предпочитаете более компактный обзор различий файлов, используйте параметр –suppress-common-lines. Это заставляет diff отображать только измененные, добавленные или удаленные строки.

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

Вывод команды diff с параметром --suppress-common-lines

Добавьте всплеск цвета

Другая утилита, называемая colordiff, добавляет цветовую подсветку к выходным данным diff. Это позволяет намного легче увидеть, какие линии имеют различия.

  Как установить статический IP-адрес в Linux в Network Manager

Используйте apt-get для установки этого пакета в вашу систему, если вы используете Ubuntu или другой дистрибутив на основе Debian. В других дистрибутивах Linux используйте вместо этого инструмент управления пакетами вашего дистрибутива Linux.

sudo apt-get install colordiff

Используйте colordiff так же, как и diff.

Вывод команды colordiff без параметров

Фактически, colordiff — это оболочка для diff, а diff выполняет всю работу за кулисами. Из-за этого все параметры diff будут работать с colordiff.

Вывод команды colordiff с параметром --suppress-common-lines

Обеспечение некоторого контекста

Чтобы найти золотую середину между отображением всех строк в файлах на экране и отображением только измененных строк, мы можем попросить diff предоставить некоторый контекст. Есть два способа сделать это. Оба способа достигают одной и той же цели — отображать несколько строк до и после каждой измененной строки. Вы сможете увидеть, что происходит в файле в том месте, где была обнаружена разница.

Первый метод использует параметр -c (скопированный контекст).

colordiff -c alpha1 alpha2

Вывод colordiff с опцией -c

Вывод diff имеет заголовок. В заголовке указаны имена двух файлов и время их модификации. Есть звездочки

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

Линия звездочек с 1,7 посередине указывает на то, что мы смотрим на строки от alpha1. Если быть точным, мы смотрим на строки с первой по седьмую. Слово «Дельта» помечается как измененное. Рядом с ним стоит восклицательный знак (!), И он красный. До и после этой строки отображаются три строки неизмененного текста, поэтому мы можем видеть контекст этой строки в файле.

Штриховая линия с 1,7 посередине говорит нам, что мы теперь смотрим на строки из alpha2. Опять же, мы смотрим на строки с первой по седьмую, где слово Дэйв в четвертой строке помечено как другое.

colordiff -C 2 alpha1 alpha2

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

Вывод colordiff с опцией -C 2

colordiff -u alpha1 alpha2

Второй параметр сравнения, который предлагает контекст, - это параметр -u (унифицированный контекст).

Вывод colordiff с параметром -u

Как и раньше, на выходе у нас есть заголовок. Два файла названы, и показано время их модификации. Перед именем альфа1 стоит тире (-), а перед именем альфа2 — знаки плюс (+). Это говорит нам о том, что тире будут использоваться для обозначения альфа1, а знаки плюса будут использоваться для обозначения альфа2. По всему списку разбросаны строки, начинающиеся со знаков (@). Эти линии отмечают начало каждого различия. Они также сообщают нам, какие строки показываются из каждого файла.

  Как использовать Keybase для шифрования файлов в Linux

Нам показаны три строки до и после строки, помеченные как разные, чтобы мы могли видеть контекст измененной строки. В едином виде линии с разницей отображаются одна над другой. Строке от alpha1 предшествует тире, а строке от alpha2 предшествует знак плюс. Это отображение в восьми строках соответствует тому, что для отображения скопированного контекста выше потребовалось пятнадцать.

colordiff -U 2 alpha1 alpha2

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

Вывод colordiff с опцией -U 2

Игнорирование пробелов и регистра

colordiff -y -W 70 test4 test5

Давайте проанализируем еще два файла: test4 и test5.  В них есть имена шести супергероев.

Вывод colordiff в файлы test4 и test5

Результаты показывают, что diff не находит ничего особенного в линиях Black Widow, Spider-Man и Thor. Он действительно отмечает изменения в линиях Капитана Америка, Железного человека и Халка.

Так в чем разница? Что ж, в test5 Халк пишется со строчной буквы «h», а у Капитана Америка есть дополнительный пробел между «Капитаном» и «Америкой». Хорошо, это ясно, но что не так с линией Ironman? Видимых отличий нет. Вот хорошее практическое правило. Если вы его не видите, ответ — пробел. Почти наверняка в конце этой строки есть пара пробелов или символ табуляции.

Если они для вас не важны, вы можете указать diff игнорировать определенные типы различий строк, в том числе:
-i: игнорировать различия в регистре.
-Z: игнорировать конечный пробел.
-b: игнорировать изменения количества белого пространства.

-w: игнорировать все изменения пробелов.

colordiff -i -y -W 70 test4 test5

Давайте попросим diff снова проверить эти два файла, но на этот раз игнорировать любые различия.

вывод из colordiff игнорировать регистр

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

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

Вывод из colordiff игнорирует конечный пробел

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

Как и предполагалось, конечный пробел должен быть разницей в строке Ironman, потому что diff больше не отмечает разницу для этой строки.  Остается Капитан Америка.  Давайте попросим diff игнорировать регистр и игнорировать все проблемы с пробелами.

Вывод из colordiff игнорирует все пробелы

Сообщая diff игнорировать различия, которые нас не волнуют, diff сообщает нам, что для наших целей файлы совпадают. У команды diff гораздо больше параметров, но большинство из них относятся к созданию машиночитаемого вывода. Их можно просмотреть в Linuxстраница руководства

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