使用“ diff”(或其他任何东西)来获取文本文件之间的字符级别差异

我想使用“ diff”来得到字符之间的行差和字符差。 例如,考虑:

文件1

abcde
abc
abcccd

文件2

abcde
ab
abccc

使用 Diff-u我得到:

@@ -1,3 +1,3 @@
abcde
-abc
-abcccd
\ No newline at end of file
+ab
+abccc
\ No newline at end of file

然而,它只显示了这些线条的变化,我想看到的是这样的:

@@ -1,3 +1,3 @@
abcde
-ab<ins>c</ins>
-abccc<ins>d</ins>
\ No newline at end of file
+ab
+abccc
\ No newline at end of file

你明白我的意思。

现在,我知道我可以使用 其他引擎来标记/检查特定行上的差异。但我宁愿使用一个工具来完成所有工作。

72606 次浏览

巨蟒的难题可以做到这一点。

文档包括一个示例 命令行程序命令行程序

确切的格式与您指定的格式不同,但是解析 ndiff 样式的输出或者修改示例程序以生成符号都很简单。

如果希望以编程方式执行此操作,Python 的 艰难是王牌。对于交互式使用,我使用 Vim 的 diff 模式(很容易使用: 只需使用 vimdiff a b调用 vim)。我偶尔也会使用 无与伦比,它可以完成几乎所有你希望从一个不同的工具。

我还没有看到任何有用的命令行工具,但是正如 Will 所指出的那样,这个有难度的示例代码可能会有所帮助。

您可以在 Solaris 中使用 cmp命令:

cmp

比较两个文件,如果它们不同,告诉第一个字节和行号它们的不同之处。

如果将文件保存在 Git 中,则可以使用 差异高亮显示脚本区分不同的版本,它将显示不同的行,并突出显示不同的行。

不幸的是,只有当删除的行数与添加的行数相匹配时,它才能工作——当行数不匹配时,会有存根代码,所以这个问题可能会在将来得到解决。

我认为更简单的解决方案总是一个好的解决方案。 在我的例子中,下面的代码对我有很大的帮助,我希望它能有所帮助 其他人。

#!/bin/env python


def readfile( fileName ):
f = open( fileName )
c = f.read()
f.close()
return c


def diff( s1, s2 ):
counter=0
for ch1, ch2 in zip( s1, s2 ):
if not ch1 == ch2:
break
counter+=1
return counter < len( s1 ) and counter or -1


import sys


f1 = readfile( sys.argv[1] )
f2 = readfile( sys.argv[2] )
pos = diff( f1, f2 )
end = pos+200


if pos >= 0:
print "Different at:", pos
print ">", f1[pos:end]
print "<", f2[pos:end]

你可以在你喜欢的终端上用以下语法比较两个文件:

$ ./diff.py fileNumber1 fileNumber2
cmp -l file1 file2 | wc

对我来说效果很好。结果的最左边数字表示不同的字符数。

Python 有一个名为 difflib的方便库,可能有助于回答您的问题。

下面是对不同的 Python 版本使用 difflib的两个 oneliner。

python3 -c 'import difflib, sys; \
print("".join( \
difflib.ndiff( \
open(sys.argv[1]).readlines(),open(sys.argv[2]).readlines())))'
python2 -c 'import difflib, sys; \
print "".join( \
difflib.ndiff( \
open(sys.argv[1]).readlines(), open(sys.argv[2]).readlines()))'

这些可能作为 shell 别名派上用场,在 .${SHELL_NAME}rc中更容易移动。

$ alias char_diff="python2 -c 'import difflib, sys; print \"\".join(difflib.ndiff(open(sys.argv[1]).readlines(), open(sys.argv[2]).readlines()))'"
$ char_diff old_file new_file

以及更具可读性的版本放入一个独立的文件。

#!/usr/bin/env python2
from __future__ import with_statement


import difflib
import sys


with open(sys.argv[1]) as old_f, open(sys.argv[2]) as new_f:
old_lines, new_lines = old_f.readlines(), new_f.readlines()
diff = difflib.ndiff(old_lines, new_lines)
print ''.join(diff)

下面是一个在线文本比较工具: Http://text-compare.com/

它可以突出显示每个不同的字符,并继续比较其他字符。

Git 有一个单词 diff,将所有字符定义为单词可以有效地为您提供一个字符 diff。但是,换行更改是 被忽略了

例子

创建一个这样的存储库:

mkdir chardifftest
cd chardifftest
git init
echo -e 'foobarbaz\ncatdog\nfox' > file
git add -A; git commit -m 1
echo -e 'fuobArbas\ncat\ndogfox' > file
git add -A; git commit -m 2

现在,做 git diff --word-diff=color --word-diff-regex=. master^ master,你会得到:

git diff

注意如何在字符级别识别添加和删除,而忽略新行的添加和删除。

你也可以尝试下面的方法:

git diff --word-diff=plain --word-diff-regex=. master^ master
git diff --word-diff=porcelain --word-diff-regex=. master^ master

彩色 性格层面 diff输出

下面是使用下面的脚本和 差异突出(它是 git 的一部分)可以做的事情:

Coloured diff screenshot

#!/bin/sh -eu


# Use diff-highlight to show word-level differences


diff -U3 --minimal "$@" |
sed 's/^-/\x1b[1;31m-/;s/^+/\x1b[1;32m+/;s/^@/\x1b[1;34m@/;s/$/\x1b[0m/' |
diff-highlight

(sed突出显示的功劳归于 @ retracile 的回答)

你可使用:

diff -u f1 f2 |colordiff |diff-highlight

screenshot

colordiff是一个 Ubuntu 软件包,你可以使用 sudo apt-get install colordiff安装它。

diff-highlight来自 git (从2.9版本开始)。它位于 /usr/share/doc/git/contrib/diff-highlight/diff-highlight。你可以把它放在 $PATH的某个地方。

我也写了我的 自己的剧本来解决这个问题使用的 最长公共子序列算法。

就是这样执行的

JLDiff.py a.txt b.txt out.html

结果是带有红色和绿色的 html。较大的文件最终确实需要较长的时间来处理,但是这样可以逐行比较真正的字符,而不需要首先逐行检查。

不是一个完整的答案,但如果 cmp -l的输出不够清晰,您可以使用:

sed 's/\(.\)/\1\n/g' file1 > file1.vertical
sed 's/\(.\)/\1\n/g' file2 > file2.vertical
diff file1.vertical file2.vertical

这些答案中的大多数都提到了使用 差异突出这个 Perl 模块。但是我不想弄清楚如何安装 Perl 模块。因此,我对它进行了一些小的更改,使其成为一个自包含的 Perl 脚本。

你可以用以下方法安装:

▶ curl -o /usr/local/bin/DiffHighlight.pl \
https://raw.githubusercontent.com/alexharv074/scripts/master/DiffHighlight.pl

用法(如果你在赞旭的回答中提到了 Ubuntu colordiff) :

▶ diff -u f1 f2 | colordiff | DiffHighlight.pl

使用方法(如果你没有) :

▶ diff -u f1 f2 | DiffHighlight.pl

Ccdiff 是这个任务的一个方便的专用工具:

ccdiff example output

默认情况下,它会突出显示颜色的差异,但是它也可以在没有颜色支持的控制台中使用。

该套件包括在 Debian 的主存储库中:

Ccdiff 是一个有色的 diff,它也会在已更改的行中显示颜色。

所有显示两个文件之间差异的命令行工具在显示可视化有用的小更改方面都存在不足。Ccdiff 尝试给出 diff --colorcolordiff的外观,但是扩展了已删除的彩色输出的显示,并将行添加到已更改行中的已删除字符和已添加字符的颜色中。

正如 评论的一个主要答案所说,你不必承诺使用 git diff:

git diff --word-diff=color --word-diff-regex=. file1 file2

enter image description here

绿色将是第二个文件添加的字符。

红色是第一个文件添加的字符。