Фатмавати Ахмад Заенури/Shutterstock.com
Нужно увидеть различия между двумя ревизиями текстового файла? Тогда diff
– это команда, которая вам нужна. Из этого туториала вы узнаете, как легко использовать diff
в Linux и macOS.
Погружение в diff
Команда diff
сравнивает два файла и выдает список различий между ними. Чтобы быть более точным, он создает список изменений, которые необходимо внести в первый файл, чтобы он соответствовал второму файлу. Если вы будете иметь это в виду, вам будет легче понять вывод diff
. Команда diff
была разработана для поиска различий между файлами исходного кода и для вывода результатов, которые могут быть прочитаны и обработаны другими программами, такими как команда patch. В этом руководстве мы рассмотрим наиболее полезные способы использования diff
.
Давайте углубимся и проанализируем два файла. Порядок файлов в командной строке определяет, какой файл diff
считает «первым файлом», а какой – «вторым файлом». В приведенном ниже примере alpha1 – первый файл, и альфа2 это второй файл. Оба файла содержат фонетический алфавит, но второй файл, alpha2, подвергся некоторому дальнейшему редактированию, так что эти два файла не идентичны.
Мы можем сравнить файлы с этой командой. Введите diff
, пробел, имя первого файла, пробел, имя второго файла и нажмите клавишу ВВОД.
diff alpha1 alpha2
Как мы анализируем этот результат? Если вы знаете, что искать, это не так уж плохо. Каждое различие перечисляется по очереди в одном столбце, и каждое различие помечается. Метка содержит цифры по обе стороны от буквы, например, 4c4
. Первое число – это номер строки в alpha1, а второе – номер строки в alpha2. Буква в середине может быть:
- c . Строка в первом файле должна быть изменена, чтобы соответствовать строке во втором файле.
- d . Строка в первом файле должна быть удалена, чтобы соответствовать второму файлу.
- a : дополнительный контент должен быть добавлен в первый файл, чтобы он соответствовал второму файлу.
4c4
в нашем примере говорит нам, что четвертая строка alpha1 должна быть изменена, чтобы соответствовать четвертой строке alpha2. Это первое различие между двумя файлами, которые diff
нашли.
Строки, начинающиеся с <
, относятся к первому файлу в нашем примере alpha1, а строки, начинающиеся с >
, относятся ко второму файлу alpha2. Строка
> Dave
говорит нам, что слово Dave является содержимым четвертой строки в alpha2. Подводя итог, нам нужно заменить Delta на Dave в четвертой строке в alpha1, чтобы эта строка соответствовала обоим файлам.
Следующее изменение обозначено 12c12
. Применяя ту же логику, это говорит нам о том, что строка 12 в alpha1 содержит слово Lima, а строка 12 в alpha2 содержит слово Linux.
Третье изменение относится к строке, которая была удалена из alpha2. Метка 21d20
расшифровывается как «строка 21 должна быть удалена из первого файла, чтобы оба файла синхронизировались со строки 20 и далее». Строка
Четвертое различие обозначено 26a26,28
. Это изменение относится к трем дополнительным строкам, которые были добавлены в alpha2. Обратите внимание на 26,28
в метке. Номера в две строки, разделенные запятой, представляют собой диапазон номеров строк. В этом примере диапазон составляет от строки 26 до строки 28. Метка интерпретируется как «в строке 26 в первом файле добавьте строки 26–28 из второго файла». Нам показаны три строки в alpha2, которые необходимо быть добавленным к альфа1. Они содержат слова Quirk, Strange и Charm.
Snappy One-Liners
Если вам нужно знать, являются ли два файла одинаковыми, используйте параметр -s
(сообщать об идентичных файлах).
diff -s alpha1 alpha3
Вы можете использовать опцию -q
(краткая), чтобы получить одинаково лаконичное утверждение о двух разных файлах.
diff -q alpha1 alpha2
Следует обратить внимание на то, что с двумя одинаковыми файлами опция -q
(краткая) полностью блокируется и ничего не сообщает.
Альтернативный взгляд
Параметр -y
(рядом) использует другой макет для описания различий в файлах.Часто удобно использовать параметр -W
(ширина) с видом рядом, чтобы ограничить число отображаемых столбцов. Это позволяет избежать появления уродливых строк, которые затрудняют чтение. Здесь мы сказали diff
производить параллельное отображение и ограничивать вывод до 70 столбцов.
diff -y -W 70 alpha1 alpha2
Первый файл в командной строке, alpha1, показан слева, а вторая строка в командной строке, alpha2, показана справа. Строки из каждого файла отображаются рядом. Рядом с этими строками в alpha2 есть символы индикатора, которые были изменены, удалены или добавлены.
- | : строка, которая была изменена во втором файле.
- <. Строка, которая была удалена из второго файла.
- > . Строка, добавленная во второй файл, которого нет в первом файле.
Если вы предпочитаете более компактную сводную информацию о различиях в файлах, используйте параметр - 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. Опять же, мы смотрим на строки с первой по седьмую, причем слово Dave на четвертой строке помечено как отличающееся.
Три строки контекста выше и ниже каждого изменения - это значение по умолчанию. Вы можете указать, сколько строк контекста вы хотите diff
предоставить. Для этого используйте параметр -C
(скопированный контекст) с заглавной буквой «C» и укажите количество строк, которое вам нужно:
colordiff -C 2 alpha1 alpha2
Вторая опция diff
, которая предлагает контекст, это опция -u
(унифицированный контекст).
colordiff -u alpha1 alpha2
Как и раньше, у нас есть заголовок на выходе. Два файла названы, и показано время их изменения. Тире ( -
) перед именем alpha1 и знаки плюс ( +
) перед именем alpha2. Это говорит нам о том, что тире будут использоваться для обозначения альфа1, а знаки плюс будут использоваться для обозначения альфа2. По всему списку разбросаны строки, начинающиеся со знаков ( @
). Эти строки отмечают начало каждого различия. Они также говорят нам, какие строки показываются из каждого файла.
Нам показывают три строки до и после строки, помеченной как отличающиеся, чтобы мы могли видеть контекст измененной строки. В едином представлении линии с разницей показаны одна над другой. Перед строкой из alpha1 стоит тире, а перед строкой из alpha2 стоит знак плюс. Это отображение достигает в восьми строках того, что для скопированного контекстного дисплея выше потребовалось пятнадцать.
Как и следовало ожидать, мы можем попросить diff
точно указать количество строк унифицированного контекста, которое мы хотели бы видеть. Для этого используйте параметр -U
(унифицированный контекст) с заглавной буквой «U» и укажите желаемое количество строк:
colordiff -U 2 alpha1 alpha2
Игнорирование пустого пространства и дела
Давайте проанализируем еще два файла, test4 и test5. В них есть имена шести супергероев.
colordiff -y -W 70 test4 test5
Результаты показывают, что diff
не находит ничего другого с линиями Черной Вдовы, Человека-Паука и Тора. Он отмечает изменения с линиями Капитан Америка, Железный человек и Халк.
Так что же отличается? Ну, в тесте 5 Халк пишется строчной буквой «h», а у «Капитана Америка» есть дополнительный пробел между «Капитаном» и «Америкой». Хорошо, это ясно, но что не так с линией Ironman? Там нет видимых различий. Вот хорошее эмпирическое правило. Если вы не видите его, ответ - пробел. В конце этой строки почти наверняка есть пробел или два, или символ табуляции.
Если они не имеют значения для вас, вы можете указать diff
игнорировать определенные типы различий строк, в том числе:
- -i : игнорировать различия в кейсе.
- -Z : игнорировать конечный пробел.
- -b : игнорировать изменения количества пробелов.
- -w : игнорировать все изменения пробелов.
Давайте попросим diff снова проверить эти два файла, но на этот раз, чтобы игнорировать любые различия в кейсе.
colordiff -i -y -W 70 test4 test5
Строки с «The Hulk» и «The Hulk» теперь считаются совпадением, и для строчных букв «h» нет разницы. Давайте попросим diff
также игнорировать конечный пробел.
colordiff -i -Z -y -W 70 test4 test5
Как и предполагалось, конечный пробел должен был отличаться в строке Ironman, потому что diff
больше не помечает разницу для этой строки. Это оставляет Капитана Америку. Давайте попросим diff
игнорировать регистр и игнорировать все проблемы пробелов.
colordiff -i -w -y -W 70 test4 test5
Говоря diff
игнорировать различия, о которых мы не беспокоимся, diff
сообщает нам, что для наших целей файлы совпадают.
Команда diff
имеет еще много опций, но большинство из них относятся к созданию машиночитаемого вывода. Их можно просмотреть на странице руководства Linux. Опции, которые мы использовали в приведенных выше примерах, позволят вам отследить все различия между версиями ваших текстовых файлов, используя командную строку и человеческие глаза.