Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Text 使用';差异';(或其他)以获取文本文件之间的字符级别差异_Text_Command Line_Diff - Fatal编程技术网

Text 使用';差异';(或其他)以获取文本文件之间的字符级别差异

Text 使用';差异';(或其他)以获取文本文件之间的字符级别差异,text,command-line,diff,Text,Command Line,Diff,我想使用“diff”来获得行差和字符差。 例如,考虑: 文件1 abcde abc abcccd abcde ab abccc 文件2 abcde abc abcccd 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 然而,它只向我展示了这些方面的变化。我想看到的是: @@

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

文件1

abcde
abc
abcccd
abcde
ab
abccc
文件2

abcde
abc
abcccd
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
@@-1,3+1,3@@
abcde
-abc
-abcccd
\文件末尾没有换行符
+ab
+abccc
\文件末尾没有换行符
你明白我的意思


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

Python的difflib可以做到这一点

文档中包括一个示例

确切的格式不是您指定的格式,但是解析ndiff样式的输出或修改示例程序以生成您的表示法将非常简单。

如果您希望以编程方式执行此操作,则Python是ace。对于交互式使用,我使用diff模式(非常容易使用:只需使用
vimdiffab
调用vim即可)。我也偶尔使用它,它几乎可以从一个diff工具中实现您所希望的所有功能


我还没有看到任何命令行工具能够有效地实现这一点,但正如威尔所说,difflib示例代码可能会有所帮助。

您可以在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]

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

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\u 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)

这是一个在线文本比较工具:


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

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 --word-diff=plain --word-diff-regex=. master^ master
git diff --word-diff=porcelain --word-diff-regex=. master^ master
彩色,字符级
diff
output

以下是您可以使用以下脚本和(git的一部分)执行的操作:

(由于突出显示了
sed
而归功于)

您可以使用:

diff -u f1 f2 |colordiff |diff-highlight
sed 's/\(.\)/\1\n/g' file1 > file1.vertical
sed 's/\(.\)/\1\n/g' file2 > file2.vertical
diff file1.vertical file2.vertical

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
的输出不够清晰,您可以使用:

diff -u f1 f2 |colordiff |diff-highlight
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
以及使用方法(如果您有zhanxw回答中提到的Ubuntu
colordiff
):

以及用法(如果您没有):

是一个方便的任务专用工具。下面是您的示例的使用情况:

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

该包包含在以下文件中:

ccdiff是一种彩色的diff,它也可以在已更改的线内显示颜色

所有显示两个文件之间差异的命令行工具在显示可视有用的细微更改方面都存在不足。ccdiff尝试提供
diff--color
colordiff
的外观和感觉,但将彩色输出的显示从彩色删除和添加行扩展到更改行中删除和添加字符的颜色


哦我希望有一个更标准化的东西(比如一个隐藏的命令行参数)。最糟糕的是,我已经超越了比较2,它甚至支持文本输出到diff的文件/控制台,但它仍然只包括行diff,而不包括字符diff。如果没有人有其他东西,我将研究python。+1为我介绍vimdiff。我发现默认颜色无法读取,但在上找到了解决方案。谢谢!我会调查的。我希望有一个更标准化的东西(比如一个隐藏的命令行参数)。但它仍然可以做得很好。如果没有人有比python更标准的版本(尽管看起来似乎没有),我将研究python。
cmp
也可以在(至少是一些)LinuxDIS上使用
▶ diff -u f1 f2 | DiffHighlight.pl