Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

Next Previous Contents

2. Что значит сравнение?

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

GNU 'diff' может показать, различаются ли файлы, не уточняя различий. Он также обеспечивает возможности не отображать отдельные виды различий, которые не важны для Вас. В большинстве случаев такие различия - это изменения в количестве "пропусков" между словами или строками. 'diff' также позволяет не отображать различия прописных букв от строчных или различия в строках, которые соответствуют некоторому заданому регулярному выражению. Эти опции могут сочетаться; например, можно игнорировать изменения и в "пропусках", и в замене регистра букв.

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

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

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

2.1 Ханки

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

Например, предположим файл 'F' состоит из трех строк 'a', 'b',' c', а файл 'G' состоит из тех же трех строк в обратном порядке 'c', 'b', 'a'. Если 'diff' посчитает общей строку 'c', команда 'diff F G' выдаст следующий результат:

     1,2d0   
     < a   
     < b    
     3a2,3   
     > b   
     > a    
Но если 'diff' посчитает вместо этого общей строку 'b', результат будет другим:

     1с1   
     < a    
     --­   
     > c    
     3c3   
     < c    
     --­   
     > a    

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

2.2 Игнорирование различий в пропусках и табуляции

Опции '-b' и '-ignore-space-change' игнорируют "пропуски" на концах строк, и считают все другие последовательности из одного или более "пропусков" одинаковыми. С этими опциями, 'diff' считает следующие две строки одинаковыми ($ обозначает конец строки):

      Here lyeth  muche rychnesse  in lytell space.   -- John Heywood$   
      Here lyeth muche rychnesse in lytell space. -- John Heywood   $   
Опции '-w' и '-ignore-all-space' более сильные, чем '-b'. Они игнорируют различия даже если один файл имеет "пропуски" там, где другой файл их не имеет. "Пропуски" включают в себя табуляцию, символы новой строки, вертикальную табуляцию, возврат каретки, и пробел; некоторые системы могут определить дополнительные символы как "пропуски". C этими опциями, 'diff' считает следующие две строки одинаковыми ($ обозначает конец строки, а '^M' - возврат коретки):

      Here lyeth  muche  rychnesse in lytell space.--  John Heywood$   
        He relyeth much erychnes  seinly tells pace.  --John Heywood   ^M$   

2.3 Игнорирование различий в чистых строках

Опции '-B' и '--ignore-blank-lines' игнорируют вставки или удаления чистых строк. Эти опции предусмотрены только для обработки строк, которые полностью пусты; они не касаются строк которые выглядят как пустые, но содержат пробел или символы табуляции. С этими опциями, например, файл содержащий:

      1.  A point is that which has no part.   
   
      2.  A line is breadthless length.   
      -- Euclid, The Elements, I   
считается одинаковым с файлом содержащим:
      1.  A point is that which has no part.   
      2.  A line is breadthless length.   
   
   
      -- Euclid, The Elements, I      

2.4 Игнорирование различий между строчными и прописными буквах

GNU 'diff' может рассматривать прописные буквы как одинаковые с соответствующими им строчными, так, что, например, будет считать `Funky Stuff', `funky STUFF', и `fUNKy stuFf' одинаковыми строками. Чтобы добиться этого, используйте опцию '-i' или '--ignore-case'.

2.5 Игнорирование строк соответствующих регулярному выражению

Для игнорирования вставок и удалений строк, соответствующих регулярному выражению используется опция '-l REGEXP' или '--ignore-matching-lines=REGEXP'. Следует избегать регулярных выражений содержащих метасимволы оболочки, чтобы избежать их неправильного толкования оболочкой. Например

                 diff -I'^[0-9]'   
игнорирует все изменения в строках начинающихся с цифры.

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

Можно определить более одного выражения для игнорирования строк, используя более одной опции '-I'. 'diff' пытается учитывать во всех строках все выражения, начиная с последнего заданного.

2.6 Обобщенное сравнение файлов

Когда необходимо выяснить только отличаются ли файлы, и не важно чем именно, можно использовать обобщенный формат вывода. В этом формате, не показывая различия между файлами, 'diff' просто сообщает отличаются ли они. Этот формат задается опциями '-q' и '--brief'.

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

Чтобы быстро показать отличаются ли файлы друг от друга, можно также использовать 'cmp'. Для одинаковых файлов, 'cmp' не производит никакого вывода. Для разных файлов 'cmp', по умолчанию выводит смещение и номер строки там, где было обнаружено первое различие. Используя опцию '-s', можно игнорировать эту информацию, так что 'cmp' не будет создавать выходного файла и сообщит лишь отличаются ли они используя выходной статус (см. "Запуск cmp").

В отличие от 'diff', 'cmp' не может сравнивать каталоги; он сравнивает только файлы.

2.7 Двоичные файлы и принудительное текстовое сравнение

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

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

Иногда может быть необходимо заставить 'diff' рассматривать файлы как текстовые. Например, сравниваются текстовые файлы, содержащие нулевые символы; 'diff' ошибочно решит, что эти файлы нетекстовые. Или сравниваются документы в формате, используемом текстовым редактором, который содержит нулевые символы для описания особого форматирования. Можно заставить 'diff' рассматривать все файлы как текстовые, и сравнивать их строка за строкой, с помощью опции '-a' или '--text'. Если файлы, сравниваемые при помощи этой опции, на самом деле не содержат текст, они возможно содержат несколько символов новой строки, и результаты работы 'diff' будут содержать ханки показывающие различия между длинными строками тех символов, какие бы они ни были, из которых состоят файлы.

Можно также заставить 'diff' рассматривать все файлы как двоичные, сообщая только отличаются ли они (но не сообщая чем). Для этого используется опция '--brief'.

В операционных системах, различающих текстовые и двоичные файлы, 'diff' обычно считывает и записывает все данные как текст. Использование опции '--binary' заставляет 'diff' считывать и записывать вместо этого двоичные данные. Эта опция не действует на Posix-совместимых системах таких как GNU или традиционный Unix. Тем не менее, многие операционные системы на персональных компьютерах отображают конец строки возвратом каретки и следующим за ним символом новой строки. На таких системах, 'diff' обычно игнорирует эти возвраты каретки при вводе и генерирует их в конце каждой обработанной строки, но с опцией '--binary' 'diff' воспринимает возрат каретки просто как еще один обрабатываемый символ, и не генерирует его в конце каждой обработанной строки. Это может быть полезно для работы с нетекстовыми файлами, которые должны быть совместимы с Posix системами.

Если необходимо сравнивать два файла байт за байтом, можно использовать программу 'cmp' с опцией '-l', чтобы выяснить значения каждого отличающегося байта в файлах. В GNU 'cmp', используя опцию '-c', можно показывать ASCII представление этих байтов. (см. подробнее "Запуск cmp").

Если 'diff3' считает, что все сравниваемые файлы - двоичные (нетекстовые файлы), он обычно сообщает об ошибке, так как такие сравнения обычно бесполезны. 'diff3' использует тот же метод, что и 'diff' чтобы определить является ли файл двоичным. Как и в 'diff', если входные файлы состоят их нескольких нетекстовых символов, но с другой стороны скорее являются текстовыми, можно заставить 'diff3' рассматривать все файлы как текстовые и сравнивать их строка за строкой с помощью опции '-a' или '--text'.


Next Previous Contents