- Подписка на печатную версию:
- Подписка на электронную версию:
- Подшивки старых номеров журнала (печатные версии)
LXF139:DrBrown3
Материал из Linuxformat.
Содержание |
Утилиты сравнения файлов
- Рассмотрим опции Linux и узнаем, зачем сравнивать файлы.
В Linux довольно много утилит сравнения файлов – выходит, людям оно нужно. Но зачем? Ну, например, кто-то взял да отредактировал ваш роман, и вы хотите оценить причиненный ущерб. Если у вас сохранилась копия оригинала, сравнение файлов быстро выявит различия. Или – у вас рабочая конфигурация Apache на одном компьютере и нерабочая на другом. Сравнение файлов настройки прольет свет на причину сбоя. Если вы программист и трудитесь над версией 1.4 своего шедевра, утилиты сравнения файлов подскажут, насколько она выросла по сравнению с 1.3. К этому случаю близок такой: нужно объединить два файла, отошедших от общего предка. Сравнение файлов поможет определить предварительные изменения, необходимые для слияния. Как мы увидим, в некоторые утилиты сравнения файлов встроена и функция слияния файлов.
Вывод командной строки утилит сравнения файлов (который можно представить как набор изменений, необходимых для превращения старой версии файла в новую) можно использовать для создания файла заплатки. Такие файлы часто называют «diffs» в честь классической утилиты командной строки. Например, на сайте ядра Linux (http://www.kernel.org) есть заплатки для обновления исходного кода одной версии ядра Linux до следующей. Чтобы загрузить их, не нужно столько трафика, сколько для загрузки полных исходных кодов ядра. Аналогично, разработчики ядра отправляют свои обновления в виде заплат.
Итак, разобравшись с мотивацией, займемся простой утилитой сравнения CMP – она существует с начала эры Unix и работает с файлами любого типа. По сути, она побайтно сравнивает файлы и сообщает, где находится первое различие. У нее есть флаг (-l), который отображает все различия, но не пытается синхронизировать содержимое: например, если удален всего один байт, различными окажутся все остальные байты в файлах. В молчаливом режиме (опция -s) утилита просто возвращает статус выхода (ноль – если файлы одинаковы, и не ноль, если нет), и ею удобно пользоваться в скриптах оболочки – например, так:
if cmp -s foo bar then echo foo and bar are identical fi
Перейдя от одной крайности к другой, расмотрим лучшую графическую утилиту сравнения файлов – Meld (http://meld.sourceforge.net). Она написана на Python. На экранном снимке показан Meld со сравнением двух версий файла /etc/fstab. Вглядевшись повнимательнее, вы увидите, что в новой версии добавлена строка комментария, одна строка удалена, а третья строка чуть изменилась. Визуальное удобство Meld в отображении различий ясно из снимка, но у него есть и другие, не столь очевидные возможности.
Например, затененные полоски по краям, справа и слева, показывают, где именно находятся различия внутри файла. Конечно, это полезнее на более длинных файлах, чем показанный здесь. Также доступна цветовая подсветка синтаксиса с GtkSourceView (как в Gedit). Другая приятная мелочь – файлы можно редактировать прямо в Meld, а diffs будут обновляться автоматически.
Есть и другие графические утилиты сравнения файлов в том же стиле – например, Tkdiff (http://sourceforge.net/projects/tkdiff), менее глянцевый, чем Meld, или Xxdiff (даже менее глянцевый, чем Tkdiff) и Kompare из KDE, который здорово выглядит на своем сайте (http://www.caffeinated.me.uk/kompare), но привести его в рабочее состояние, чтобы сделать снимок, было непросто.
В более дешевом сегменте рынка, по крайней мере в смысле визуальной привлекательности, классическая утилита сравнения файлов – это diff. Посмотрим, как она представит изменения в тех же двух файлах fstab:
$ diff fstab.old fstab.new 1a2 > # Home directories on separate drive 4d4 < /dev/fd0 /media/floppy auto rw,noauto,user,sync 0 0 6c6 < /dev/hda1 swap swap pri=42 0 0 --- > /dev/hda1 swap swap defaults 0 0
Изменения в diff помечены буквами a (добавлено), d (удалено) и c (изменено). Числа относятся к номерам строк в файлах слева и справа. Таким образом, 6c6 означает, что изменение было, и мы находимся на строке 6 в обоих файлах. Строки, начинающиеся с символа <, показывают отличия в файле слева, а строки с > показывают отличия в файле справа. Понять, что происходит, чуть сложнее по сравнению с графическими утилитами. diff также не пытается отметить, где изменения находятся в строке. Однако у diff есть еще тузы в рукаве. Она может выполнять параллельное сравнение (флаг -y) со множеством опций, позволяющих игнорировать различия определенных типов: например, в регистре или из-за преобразования табуляции в пробелы. Некоторые графические утилиты внутри используют diff. Всмотревшись в экранный снимок Tkdiff, в левом верхнем углу вы увидите выпадающий список, где отображен соответствующий вывод diff. Как и CMP, diff очень стар. Обе утилиты описаны в моем руководстве по Linux Edition 6, датированным 1974 годом.
Программы для сравнения файлов писать весьма нелегко. Нельзя просто пройти по файлам, сравнивая их строка за строкой. После обнаружения вставленных или удаленных строк нужно возвращаться к синхронизированному состоянию. И нельзя только лишь синхронизироваться по следующим совпадающим строкам. Истинная цель состоит в определении минимально достаточного набора отличий, и если файлы отличаются сильно, это задача нетривиальная.
Увеличим охват
Отъехав с камерой подальше, мы обнаружим, что с помощью этих утилит можно сравнивать целые деревья каталогов. В Meld, например, есть стандартное представление деревьев двух файловых систем в стиле проводника. На снимке выше мы сравниваем две версии дерева исходного кода ядра Linux, и легко видеть, какие файлы были добавлены (показаны зеленым), удалены (вычеркнуты серым) и изменены (красным). Щелчок на измененном файле откроет новую вкладку, где вы увидите diff для этого файла.
То же самое можно сделать командой diff -r, хотя при сравнении двух больших деревьев каталогов, таких как исходники ядра, объем выводимых данных будет огромен.
В порядке более скромного примера сравнения дерева каталогов – опытный системный администратор может заснять базовые системные настройки, упаковав в архив содержимое каталога '/etc с сохранением структуры каталогов. Сравнив его с текущим содержимым каталога (на другом компьютере или некоторое время спустя), легко увидеть, где конфигурация изменилась.
Есть еще одна великолепная утилита сравнения файлов, достойная описания, но ее работу невозможно показать на печатной странице, так как в ее основе лежит анимация. Она называется Diffamation (занятно, потому что ее пишут французы, а по-французски это значит «клевета»). Различия в файлах в ней показываются с помощью плавно анимированных текстовых переходов, и программа особенно эффективна для показа эволюции текста документа за время его жизни. Зайдите на http://www.aviz.fr/diffamation и посмотрите видеоролик. Отличная работа.
Слияние
Слияние – процесс, противоположный поиску различий в файлах; ну, нечто вроде. Обычно оно необходимо в тех случаях, когда два файла возникли в один и тот же момент (то есть у них был общий предок), но потом редактировались независимо и стали отличаться. Например, это происходит с файлами исходного кода, когда отделившаяся команда разработчиков ответвляет проект, или с файлами конфигурации на двух первоначально одинаковых компьютерах, настроенных независимо друг от друга. Слияние – процесс объединения обоих измененных файлов в один. Это не точная наука, и при слиянии обычно возникают конфликты, для разрешения требующие вмешательства человека.
Meld умеет выполнять операцию слияния. Взгляните на черные стрелки посреди первого экранного снимка. Щелкая по ним, можно выполнять слияние изменений одно за другим в любом направлении.Возможнои трехстороннее слияние, то есть показ различий между двумя файлами, имеющими общего предка, и объединение обоих измененных файлов в один.
Слияние деревьев каталогов подводит нас к утилитам синхронизации. Классическая утилита здесь – rsync, но это «поездка в один конец» (изменения можно производить только в одном направлении). В качестве утилиты двусторонней синхронизации попробуйте Unison (http://www.cis.upenn.edu/~bcpierce/unison). У нее есть приятное свойство кроссплатформенности между различными вариантами Unix и Windows.
А если это не текст?
Утилиты, о которых мы говорили, работают только с текстовыми файлами, и их поле деятельности пугающе сужается при переходе к файлам других типов. В OpenOffice.org предусмотрено сравнение документов. Двустороннего представления документов нет, но различия отмечаются встроенной разметкой. Документы не сравниваются полностью: вы скачете от одного изменения к другому, принимая или отклоняя каждое; однако нередки ошибки определения минимально достаточного набора различий – часто помечается пол-абзаца, когда различие всего в несколько слов. Это поведение показано на рисунке.
Для сравнения изображений имеются утилиты, определяющие дубликаты в вашей коллекции фотографий, но все они, кажется, для Windows. Порывшись, я обнаружил программу под названием Perceptualdiff, которая работает в Linux и использует «вычислительную модель визуальной системы человека» для определения видимого различия между двумя изображениями (поддерживаются форматы TIFF и PNG). Можно задать несколько параметров (указав чувствительность сравнения) и получить простой результат «одинаковы/неодинаковы» (PASS/FAIL):
$ perceptualdiff screenshot1.png screenshot2.png FAIL: Images are visibly different 114 pixels are different
Нечто большее, наверное, уже за пределами интеллекта компьютера.