如何针对单个基本文件“区分”多个文件?

时间:2009-04-21 14:53:01

标签: delphi diff

我有一个配置文件,我认为它是我的“基础”配置。我想将最多10个其他配置文件与该单个基本文件进行比较。我正在寻找一个报告,其中每个文件都与基本文件进行比较。

我一直在看diff和sdiff,但他们并没有完全提供我想要的东西。

我已经考虑过单独针对每个文件区分基础,但我的问题会变成合并到报告中。理想情况下,如果所有10个配置文件中都缺少相同的行(与基本配置相比),我希望以易于可视化的方式报告。

请注意,有些行在几个配置文件中缺失(当与基础单独比较时)。我希望能够把它们放在同一条线上(如上所述)。

请注意,上面的屏幕截图只是一个模型,而不是一个实际的应用程序。

我已经看过使用一些Delphi控件并编写自己的(我有Delphi 2007),但如果有一个程序已经这样做了,我更喜欢它。

我看过的Delphi控件是TDiffTrmDiff* components included in rmcontrols

10 个答案:

答案 0 :(得分:10)

对于仍然想知道如何做到这一点的人来说,diffuse是最接近的答案,它通过显示所有文件并在neighboors之间进行三向合并来进行N路合并。

答案 1 :(得分:4)

现有的差异/合并工具都不能满足您的需求。根据您的示例屏幕截图,您正在寻找一种算法,该算法可以对多个文件执行对齐,并根据线条相似度给出适当的权重。

第一个问题是根据线相似性加权对齐。最流行的对齐算法,包括GNU diff,TDiff和TrmDiff使用的对齐算法,基于线条哈希进行对齐,只检查线条是否完全匹配。您可以预处理行以删除空格或将所有内容更改为小写,但就是这样。添加,删除或更改字母以及整行不同的对齐方式。此时不同线条的任何对齐都是偶然的。

Beyond Compare确实考虑了线条相似性,但它实际上只适用于双向比较。比较吧!也有某种相似性算法,但它也仅限于双向比较。它可以大大减慢比较速度,而且我不知道任何其他组件或程序,商业或开源,甚至尝试。

另一个问题是您还需要进行多文件比较。这意味着要么多次运行双向差异算法并将结果拼接在一起,要么找到一次执行多个对齐的算法。

拼接很困难:您的示例显示原始文件可能缺少行,因此您需要将每个文件与每个其他文件进行比较以获得一堆对齐,然后您需要解决匹配这些对齐的最佳方法。一个天真的拼接算法很容易做到,但它会被琐碎的匹配(例如空行)弄乱。

有些研究论文涵盖了同时对齐多个序列,但它们通常专注于DNA比较,你必须自己编写代码。维基百科涵盖了很多基础知识,然后您可能需要切换到Google学术搜索。

答案 2 :(得分:1)

尝试Scooter Software的Beyond Compare。它支持3路合并,用Delphi / Kylix编写,支持多平台。我已经非常广泛地使用它(甚至通过VPN)并且表现良好。

答案 3 :(得分:1)

for file in file1 file2 file3 file4 file5;回显“$ f \ n \ n”>> OUTF; diff $ f baseFile>> OUTF; echo“\ n \ n”>> OUTF;完成

答案 4 :(得分:1)

Diff3应该有所帮助。如果您使用的是Windows,则可以使用Cygwin或diffutils

答案 5 :(得分:1)

我制作了自己的差异工具DirDiff,因为我不希望屏幕上匹配两次的部分,以及相互之间的不同部分,以便于比较。您可以在目录模式下在具有相同副本的基本文件副本的目录上使用它。 它不会渲染diff的导出,但我会list it as a feature request

答案 6 :(得分:0)

您可能希望查看一些Merge组件,因为您所描述的正是Merge工具在公共库,版本控制文件和本地文件之间所做的事情。除了你想要超过2个文件(+ base)...
只需我0.02美元

答案 7 :(得分:0)

对于基于Windows的文件差异,

SourceGear Diffmerge很好(而且是免费的)。

答案 8 :(得分:0)

我知道这是一个老线程,但vimdiff确实(几乎)正是你正在寻找的东西,并且能够直接从差异视角编辑文件。

答案 9 :(得分:0)

但是这些解决方案仍然没有超过3个文件。 我做的比较麻烦,但出于同样的目的(比较多个配置文件的内容,除了内存和BASH变量之外没有限制)

while循环将文件读入数组:

loadsauce () {
index=0
while read SRCCNT[$index]
 do let index=index+1
 done < $SRC
}

再次针对目标文件

loadtarget () {
index=0
while read TRGCNT[$index]
 do let index=index+1
 done < $TRG
}

字符串比较

brutediff () {
# Brute force string compare, probably duplicates diff
# This is very ugly but it will compare every line in SRC against every line in TRG
# Grep might to better, version included for completeness
for selement in $(seq 0 $((${#SRCCNT[@]} - 1)))
 do for telement in $(seq 0 $((${#TRGCNT[@]} - 1)))
  do [[ "$selement" == "$telement" ]] && echo "${selement} is in ${SRC} and ${TRG}" >> $OUTMATCH
  done
 done
}

最后是针对文件列表进行循环

for sauces in $(cat $SRCLIST)
 do echo "Checking ${sauces}..."
  loadsauce
  loadtarget
  brutediff
  echo -n "Done, "
 done

它仍然没有经过测试/错误和不完整(比如整理重复项或为每行使用常见文件编译列表),但这绝对是OP所要求的方向。 我确实认为Perl会更好。