Linux как сравнить файлы по содержимому

Сравнение файлов в консоли Linux

Нужно увидеть различия между двумя ревизиями текстового файла? Тогда diff — это команда, которая вам нужна. Из этого туториала вы узнаете, как легко использовать diff в Linux и macOS.

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

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

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

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

Как мы анализируем этот результат? Если вы знаете, что искать, это не так уж плохо. Каждое различие перечисляется по очереди в одном столбце, и каждое различие помечается. Ярлык содержит цифры по обе стороны от буквы, например 4c4. Первое число — это номер строки в alpha1, а второе — номер строки в alpha2. Буква в середине может быть:

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

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

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

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

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

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

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

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

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

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

  • |: Строка, которая была изменена во втором файле.
  • : Строка, добавленная ко второму файлу, которого нет в первом файле.
Читайте также:  All system call linux

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

Добавьте цветовую подсветку

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

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

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

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

Предоставление определённого контекста

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

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

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

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

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

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

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

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

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

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

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

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

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

Читайте также:  Утилита исправляющая ошибки windows

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

Если они не имеют значения для вас, вы можете diff игнорировать определенные типы различий строк, в том числе:

  • -i: игнорировать различия в случае.
  • -Z: игнорировать конечные пробелы.
  • -b: игнорировать изменения количества пустого пространства.
  • -w: игнорировать все изменения пробелов.

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

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

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

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

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

Источник

Построчное сравнение текстовых файлов в Linux с помощью утилиты diff — часть 2

Оригинал: How to do line-by-line comparison of files in Linux using diff command — Part II
Автор: Himanshu Arora
Дата публикации: 2 января 2017 г.
Перевод: А.Панин
Дата перевода: 13 февраля 2017 г.

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

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

Но перед тем, как перейти к рассмотрению параметров командной строки утилиты, следует упомянуть о том, что все примеры из данной статьи были протестированы в системе Ubuntu 14.04 с Bash версии 4.3.11(1) и diff версии 3.3.

Параметры командной строки утилиты diff

1. Вывод сообщения об идентичности файлов

По умолчанию в случае установления факта идентичности файлов утилита diff не выводит никаких сообщений.

Но существует специальный параметр командной строки ( -s ), в случае использования которого данная утилита будет сообщать об идентичности файлов:

2. Копируемый и унифицированный контексты вывода

Утилита diff поддерживает, по сути, два различных формата вывода. Копируемый контекст вывода (copied context) активируется с помощью параметра командной строки -c , а унифицированный контекст (unified context) — с помощью параметра командной строки -u . Это пример первого первого формата вывода:

Очевидно, что в случае использования копируемого контекста вывода отличающиеся строки маркируются с помощью символа восклицательного знака ( «!» ).

А это пример унифицированного контекста вывода:

В случае использования этого формата вывода символы «+» и «-» перед строками соответствуют различиям в файлах: с помощью символа «-» маркируются строки из файла с именем file1, отсутствующие в файле с именем file2, а с помощью символа «+» — строки из файла с именем file2, которые должны быть добавлены в файл с именем file1.

Читайте также:  Восстановление после ошибок windows загрузка файлов

3. Вывод сценария для текстового редактора ed

Утилита diff также может выводить последовательности команд, которые, в свою очередь, могут использоваться текстовым редактором ed для преобразования оригинального файла (в наших примерах с именем file1) в новый файл (с именем file2). Вы можете получить такой вывод следующим образом.

Предположим, что файлы с именами file1 и file2 имеют следующие различия:

Теперь используем параметр командной строки -e для генерации вывода, понятного текстовому редактору ed , после чего перенаправим этот вывод в отдельный файл:

В данном случае в файле будет сохранен следующий вывод утилиты:

После этого вам придется самостоятельно добавить команду «w» в конец этого файла:

Теперь вы можете выполнить следующую команду:

В результате файлы с именами file1 и file2 станут идентичными:

Если вас интересует дополнительная информация, связанная с данной функцией утилиты, вы можете перейти по этой ссылке .

4. Генерация вывода в двух столбцах

Обычно diff генерирует вывод следующего формата:

Но существует специальный параметр командной строки ( -y ), который сообщает утилите о необходимости вывода данных в двух отдельных столбцах. А это пример такого вывода:

Очевидно, что при использовании данного формата вывода символ «|» используется для маркировки отличающихся строк.

5. Сокрытие идентичных строк

Если вы внимательно рассмотрите вывод из предыдущего примера (из расположенного выше раздела 4), вы обнаружите, что при использовании параметра командной строки -y утилита diff выводит не только измененные, но и идентичные строки обрабатываемых файлов. В том случае, если вам нужно убрать идентичные строки из вывода, вы можете воспользоваться параметром —suppress-common-lines .

6. Вывод имен функций языка C, содержащих измененный код

При использовании утилиты diff для сравнения двух файлов исходного кода на языке C может использоваться специальный параметр ( -p ), который сообщает утилите о необходимости вывода имен функций, в коде которых были обнаружены изменения. Например, предположим, что требуется сравнить два следующих файла исходного кода на языке C:

Файл с именем file1.c:

Файл с именем file2:

Это результат обычного сравнения этих файлов:

А это результат сравнения тех же файлов с использованием параметра -p :

Очевидно, что в случае использования параметра командной строки -p diff генерирует более подробный вывод с маркировкой измененных строк с помощью символа восклицательного знака ( «!» ).

7. Рекурсивное сравнение содержимого поддиректорий

Утилита diff также позволяет осуществлять рекурсивное сравнение содержимого поддиректорий, но этот режим работы не активирован по умолчанию. Я подразумевал, что при использовании данной команды:

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

8. Обработка отсутствующих файлов как пустых

Утилита diff также поддерживает параметр, с помощью которого вы можете сообщить ей о том, что следует рассматривать отсутствующие файлы как пустые. Если вы сравните файлы с именами file1 и file3 (причем последнего файла не существует), по умолчанию diff выведет сообщение об ошибке:

В этом нет ничего плохого; по сути, данное поведение является вполне обоснованным. Но бывают случаи, когда необходимо избежать вывода сообщений об ошибках (возможно, при использовании diff в рамках сценариев командной оболочки), в которых вы можете воспользоваться параметром -N для обработки отсутствующих файлов как пустых и продолжения сравнения файлов.

Заключение

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

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

Источник

Оцените статью