Программа diff
в ее различных воплощениях довольно хорошо вычисляет разницу между двумя текстовыми файлами и выражает ее более компактно, чем показывает оба файла целиком. Он показывает разницу в виде последовательности вставленных и удаленных кусков строк (или измененных строк в некоторых случаях, но это эквивалентно удалению, за которым следует вставка). Одна и та же или очень похожая программа или алгоритм используются patch
и системами управления версиями для минимизации памяти, необходимой для представления различий между двумя версиями одного и того же файла. Алгоритм обсуждается здесь и здесь .
Но он падает, когда блоки текста перемещаются внутри файла.
Предположим, у вас есть следующие два файла, a.txt
иb.txt
(представьте, что они оба состоят из сотен строк, а не всего 6):
a.txt b.txt
----- -----
1 4
2 5
3 6
4 1
5 2
6 3
diff a.txt b.txt
показывает это:
$ diff a.txt b.txt
1,3d0
< 1
< 2
< 3
6a4,6
> 1
> 2
> 3
Изменение с a.txt
на b.txt
может быть выражено как «Возьмите первые три строки и переместите их в конец», но diff
показывает полное содержимое перемещенного фрагмента строк дважды, упуская возможность очень кратко описать это большое изменение.
Обратите внимание, что diff -e
показывает блок текста только один раз, но это потому, что он не показывает содержимое удаленных строк.
Существует ли вариант алгоритма diff
, в котором (a)сохраняет способность diff
представлять вставки и удаления, а (b)эффективно представляет перемещенные блоки текста без показать все их содержимое?