LXF139:DrBrown3

Материал из Linuxformat.

Перейти к: навигация, поиск

Содержание

Утилиты сравнения файлов

Рассмотрим опции Linux и узнаем, зачем сравнивать файлы.

В Linux до­воль­но мно­го ути­лит срав­не­ния фай­лов – вы­хо­дит, лю­дям оно нуж­но. Но за­чем? Ну, на­при­мер, кто-то взял да от­ре­дак­ти­ро­вал ваш ро­ман, и вы хо­ти­те оце­нить при­чи­нен­ный ущерб. Ес­ли у вас со­хра­ни­лась ко­пия ори­ги­на­ла, срав­не­ние фай­лов бы­ст­ро вы­явит раз­ли­чия. Или – у вас ра­бо­чая кон­фи­гу­ра­ция Apache на од­ном ком­пь­ю­те­ре и не­ра­бо­чая на дру­гом. Срав­не­ние фай­лов на­строй­ки проль­ет свет на при­чи­ну сбоя. Ес­ли вы про­грам­мист и тру­ди­тесь над вер­си­ей 1.4 сво­его ше­дев­ра, ути­ли­ты срав­не­ния фай­лов под­ска­жут, на­сколь­ко она вы­рос­ла по срав­не­нию с 1.3. К это­му слу­чаю бли­зок та­кой: нуж­но объ­е­ди­нить два фай­ла, ото­шед­ших от об­ще­го пред­ка. Срав­не­ние фай­лов по­мо­жет оп­ре­де­лить пред­ва­ри­тель­ные из­ме­не­ния, не­об­хо­ди­мые для слия­ния. Как мы уви­дим, в не­ко­то­рые ути­ли­ты срав­не­ния фай­лов встрое­на и функ­ция слия­ния фай­лов.

Вы­вод ко­манд­ной стро­ки ути­лит срав­не­ния фай­лов (ко­то­рый мож­но пред­ста­вить как на­бор из­ме­не­ний, не­об­хо­ди­мых для пре­вра­ще­ния ста­рой вер­сии фай­ла в но­вую) мож­но ис­поль­зо­вать для соз­да­ния фай­ла за­плат­ки. Та­кие фай­лы час­то на­зы­ва­ют «diffs» в честь клас­си­че­ской ути­ли­ты ко­манд­ной стро­ки. На­при­мер, на сай­те яд­ра Linux (http://www.kernel.org) есть за­плат­ки для об­нов­ле­ния ис­ход­но­го ко­да од­ной вер­сии яд­ра Linux до сле­дую­щей. Что­бы за­гру­зить их, не нуж­но столь­ко тра­фи­ка, сколь­ко для за­груз­ки пол­ных ис­ход­ных ко­дов яд­ра. Ана­ло­гич­но, раз­ра­бот­чи­ки яд­ра от­прав­ля­ют свои об­нов­ле­ния в ви­де за­плат.

Итак, ра­зо­брав­шись с мо­ти­ва­ци­ей, зай­мем­ся про­стой ути­ли­той срав­не­ния CMP – она су­ще­ст­ву­ет с на­ча­ла эры Unix и ра­бо­та­ет с фай­ла­ми лю­бо­го ти­па. По су­ти, она по­байт­но срав­ни­ва­ет фай­лы и со­об­ща­ет, где на­хо­дит­ся пер­вое раз­ли­чие. У нее есть флаг (-l), ко­то­рый ото­бра­жа­ет все раз­ли­чия, но не пы­та­ет­ся син­хро­ни­зи­ро­вать со­дер­жи­мое: на­при­мер, ес­ли уда­лен все­го один байт, раз­лич­ны­ми ока­жут­ся все ос­таль­ные бай­ты в фай­лах. В мол­ча­ли­вом ре­жи­ме (оп­ция -s) ути­ли­та про­сто воз­вра­ща­ет ста­тус вы­хо­да (ноль – ес­ли фай­лы оди­на­ко­вы, и не ноль, ес­ли нет), и ею удоб­но поль­зо­вать­ся в скрип­тах обо­лоч­ки – на­при­мер, так:

Представление фай­лов в Meld ли­цом к ли­цу ви­зу­аль­но под­во­дит к раз­ли­чи­ям.

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 не так от­по­ли­ро­ван, как Meld, но мо­жет про­ве­рять фай­лы из раз­лич­ных сис­тем кон­тро­ля вер­сий.

Есть и дру­гие гра­фи­че­ские ути­ли­ты срав­не­ния фай­лов в том же сти­ле – на­при­мер, 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 срав­ни­ва­ет два де­ре­ва ис­ход­но­го ко­да яд­ра. Лег­ко най­ти но­вые, уда­лен­ные, из­ме­нен­ные и не­из­ме­нен­ные фай­лы.

Отъ­е­хав с ка­ме­рой по­даль­ше, мы об­на­ру­жим, что с по­мо­щью этих ути­лит мож­но срав­ни­вать це­лые де­ре­вья ка­та­ло­гов. В 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 срав­ни­ва­ет до­ку­мен­ты, под­све­чи­вая из­ме­не­ния, но час­то (как здесь) не уме­ет най­ти ми­ни­маль­ные от­ли­чия.

Ути­ли­ты, о ко­то­рых мы го­во­ри­ли, ра­бо­та­ют толь­ко с тек­сто­вы­ми фай­ла­ми, и их по­ле дея­тель­но­сти пу­гаю­ще су­жа­ет­ся при пе­ре­хо­де к фай­лам дру­гих ти­пов. В OpenOffice.org пре­ду­смот­ре­но срав­не­ние до­ку­мен­тов. Дву­сто­рон­не­го пред­став­ле­ния до­ку­мен­тов нет, но раз­ли­чия от­ме­ча­ют­ся встро­ен­ной раз­мет­кой. До­ку­мен­ты не срав­ни­ва­ют­ся пол­но­стью: вы ска­че­те от од­но­го из­ме­не­ния к дру­го­му, при­ни­мая или от­кло­няя ка­ж­дое; од­на­ко не­ред­ки ошиб­ки оп­ре­де­ле­ния ми­ни­маль­но дос­та­точ­но­го на­бо­ра раз­ли­чий – час­то по­ме­ча­ет­ся пол-аб­за­ца, ко­гда раз­ли­чие все­го в не­сколь­ко слов. Это по­ве­де­ние по­ка­за­но на рисунке.

Для срав­не­ния изо­бра­же­ний имеются ути­ли­ты, оп­ре­де­ляю­щие дуб­ли­ка­ты в ва­шей кол­лек­ции фо­то­гра­фий, но все они, ка­жет­ся, для Windows. По­рыв­шись, я об­на­ру­жил про­грам­му под на­зва­ни­ем Perceptualdiff, ко­то­рая ра­бо­та­ет в Linux и ис­поль­зу­ет «вы­чис­ли­тель­ную мо­дель ви­зу­аль­ной сис­те­мы че­ло­ве­ка» для оп­ре­де­ле­ния ви­ди­мо­го раз­ли­чия ме­ж­ду дву­мя изо­бра­же­ния­ми (под­дер­жи­ва­ют­ся фор­ма­ты TIFF и PNG). Мож­но за­дать не­сколь­ко па­ра­мет­ров (ука­зав чув­ст­ви­тель­ность срав­не­ния) и по­лу­чить про­стой ре­зуль­тат «оди­на­ко­вы/не­оди­на­ко­вы» (PASS/FAIL):

$ perceptualdiff screenshot1.png screenshot2.png
FAIL: Images are visibly different 114 pixels are different

Не­что боль­шее, на­вер­ное, уже за пре­де­ла­ми ин­тел­лек­та ком­пьютера.

Личные инструменты
  • Купить электронную версию
  • Подписаться на бумажную версию