Команда diff3

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

Базовый синтаксис команды выглядит следующим образом:

$ diff3 [параметры] файл1 файл2 файл3

Утилита поддерживает ряд параметров, большая часть которых позволяет генерировать сценарии для объединения файлов с помощью утилиты ed. В частности, для генерации таких файлов чаще всего используется параметр -x, позволяющий добавить отличия между всеми файлами в файл1. Также существует аналогичный параметр -e, позволяющий добавить отличия между файлами файл2 и файл3 в файл1, что требуется крайне редко. Параметр -3 позволяет создать сценарий для добавления отличий между файлами файл1 и файл3 в файл файл1, что также может понадобиться в редких случаях. Параметр -i позволяет добавить в сценарий команды для автоматического завершения работы утилиты ed. Параметр -b позволяет игнорировать различия пустых строк, то есть, пропускать все находящиеся в них пробелы и символы табуляции.

При обычном использовании в выводе утилиты могут использоваться следующие служебные метки:

  • ====1файл1 отличается от стальных
  • ====2файл2 отличается от стальных
  • ====3файл3 отличается от стальных
  • ==== — отличаются все три файла

После служебной метки может следовать метка, описывающая отличия файлов в формате «номер-файла:начальная-строка,конечная-строка» с последующим измененным текстом или метка в формате «номер-файла:начальная-строка» с последующим текстом, который должен быть добавлен после строки с заданным номером.

Примеры использования

Сравнение трех файлов

Для начала рассмотрим содержимое трех текстовых файлов, которые будут сравниваться.

Это содержимое файла sample1.txt:

It is a truth universally acknowledged, that a single man in possession
of a good fortune, must be in want of a wife.

However little known the feelings or views of such a man may be on his
first entering a neighbourhood, this truth is so well fixed in the minds
of the surrounding families, that he is considered the rightful property
of some one or other of their daughters.

Это — содержимое файла sample2.txt:

However little known the feelings or views of such a man may be on his
first entering a neighbourhood, this truth is so well fixed in the minds
of the surrounding families, that he is considered the rightful property
of some one or other of their daughters.

"My dear Mr. Bennet," said his lady to him one day, "have you heard that
Netherfield Park is let at last?"

Mr. Bennet replied that he had not.

А это — содержимое файла sample3.txt:

However little known the feelings or views of such a man may be on his
first entering a neighbourhood, this truth is so well fixed in the minds
of the surrounding families, that he is considered the rightful property
of some one or other of their daughters.

"My dear Mr. Bennet," said his lady to him one day, "have you heard that
Netherfield Park is let at last?"

Для сравнения трех текстовых файлов достаточно вызвать утилиту diff3 без каких-либо параметров:

$ diff3 sample1.txt sample2.txt sample3.txt

В результате будет получен следующий вывод, представляющий собой описание различий содержимого этих файлов:

====1
1:1,3c
  It is a truth universally acknowledged, that a single man in possession
  of a good fortune, must be in want of a wife.
 
2:0a
3:0a
====
1:7a
2:5,9c
 
  "My dear Mr. Bennet," said his lady to him one day, "have you heard that
  Netherfield Park is let at last?"
 
  Mr. Bennet replied that he had not.
3:5,7c
 
  "My dear Mr. Bennet," said his lady to him one day, "have you heard that
  Netherfield Park is let at last?"

Несложно заметить, что вывод в данном формате плохо читается, так как предназначен для программной обработки. Итак, для объединения файлов в первую очередь следует открыть первый файл sample1.txt (====1) и добавить с первой по третью строки включительно из из этого файла (1:1,3c) в начало второго и третьего файлов sample2.txt (2:0a) и sample3.txt (3:0a) соответственно. После этого следует изменить строки с 5 по 9 включительно второго файла sample2.txt (2:5,9c) и строки с 5 по 7 включительно третьего файла sample3.txt (3:5,7c), удалив их для приведения этих файлов в соответствие с первым файлом sample1.txt.

Создание сценария для утилиты ed

Для того, чтобы создать сценарий преобразования файлов, совместимый с утилитой ed, следует воспользоваться параметром -e. Также можно использовать параметр -i для добавления в сценарий инструкций для автоматического завершения работы утилиты. Также разумным решением будет сохранение сценария в отдельном файле с именем sample.ed:

$ diff3 -ei sample1.txt sample2.txt sample3.txt > sample.ed

В результате будет сгенерирован файл сценария утилиты ed под названием sample.ed со следующим содержимым:

7a

"My dear Mr. Bennet," said his lady to him one day, "have you heard that
Netherfield Park is let at last?"
.
w
q

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

$ ed - sample1.txt < sample.ed

В итоге файл sample1.txt примет следующий вид:

It is a truth universally acknowledged, that a single man in possession
of a good fortune, must be in want of a wife.

However little known the feelings or views of such a man may be on his
first entering a neighbourhood, this truth is so well fixed in the minds
of the surrounding families, that he is considered the rightful property
of some one or other of their daughters.

"My dear Mr. Bennet," said his lady to him one day, "have you heard that
Netherfield Park is let at last?"

Очевидно, что силами созданного сценария в оригинальный файл sample1.txt были добавлены строки, встречающиеся во втором и третьем файле, а именно sample2.txt и sample3.txt. Да, утилита работает по-разному при наличии и отсутствии параметров и это нужно учитывать.