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

Vit*_*lyB 81 diff command-line text

我想使用'diff'来获得字符差异和字符差异.例如,考虑:

档案1

abcde
abc
abcccd
Run Code Online (Sandbox Code Playgroud)

档案2

abcde
ab
abccc
Run Code Online (Sandbox Code Playgroud)

使用diff -u我得到:

@@ -1,3 +1,3 @@
 abcde
-abc
-abcccd
\ No newline at end of file
+ab
+abccc
\ No newline at end of file
Run Code Online (Sandbox Code Playgroud)

但是,它只向我显示这些行的变化.我希望看到的是:

@@ -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
Run Code Online (Sandbox Code Playgroud)

你得到我的漂移.

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

小智 58

Git有一个单词diff,将所有字符定义为单词有效地为你提供了一个字符差异.但是,换行更改是IGNORED.

例:

创建一个这样的存储库:

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
Run Code Online (Sandbox Code Playgroud)

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

git diff http://oi60.tinypic.com/160wpb4.jpg

请注意如何在字符级别识别添加和删除,同时忽略新行的添加和删除.

你也可以尝试
git diff --word-diff=color --word-diff-regex=. master^ master

git diff --word-diff=color --word-diff-regex=. master^ master

  • 你根本不需要创建一个repo,你可以简单地在文件系统的任何地方给git diff任意两个文件并且它可以工作.你的命令对我很有用,谢谢!`git diff --word-diff = color --word-diff-regex =.file1 file2` (58认同)
  • 我需要在上面的@ qwertzguys'响应中添加`--no-index`,以便在git repo之外为它工作.所以:`git diff --no-index --word-diff = color --word-diff-regex =.file1 file2` (19认同)
  • 对于稍微更紧凑的命令 `--word-diff=color --word-diff-regex=.` 可以替换为 `--color-words=.` (5认同)
  • 这非常有帮助!如果可以的话,我会作为软件开发人员 +1 一次,作为作者/作家再 +1 两次。不像在代码中,行往往相当短,在写论文/故事时,每个段落往往采用长的自动换行行的形式,这个特性使得差异实际上在视觉上很有用。 (3认同)
  • git diff在常规设置中不起作用:git diff --no-index --word-diff = color --word-diff-regex =。&lt;(echo string1)&lt;(echo string2)..没什么,但这有效:diff --color &lt;(echo string1)&lt;(echo string2)。 (2认同)
  • @NathanBell 我也需要在存储库中添加 `--no-index` (2认同)

zha*_*nxw 24

您可以使用:

diff -u f1 f2 |colordiff |diff-highlight
Run Code Online (Sandbox Code Playgroud)

截图

colordiff是一个Ubuntu包.你可以使用它安装它sudo apt-get install colordiff.

diff-highlight来自git(自2.9版本起).它位于/usr/share/doc/git/contrib/diff-highlight/diff-highlight.你可以把它放在你的某个地方$PATH.或者从差异化的项目中获取它.

  • colordiff也适用于Mac的自制软件:`brew install colordiff` (6认同)
  • 在Mac上,您可以在$(brew --prefix git)/ share / git-core / contrib / diff-highlight / diff-highlight中找到`diff-highlight`。 (4认同)
  • 如果你没有使用brew安装git - `diff-highlight`也可以使用python的pip安装 - `pip install diff-highlight`(即使git是通过brew安装的,我更喜欢它) (2认同)

Ned*_*Ned 18

如果你想以编程方式执行此操作,Python的difflib是ace.对于交互式使用,我使用vim的 diff模式(很容易使用:只需调用vim vimdiff a b).我也偶尔使用Beyond Compare,它可以从diff工具中完成你所希望的一切.

我没有看到任何有用的命令行工具,但正如Will所说,difflib示例代码可能有所帮助.

  • +1给我介绍vimdiff.我发现默认颜色不可读,但在http://stackoverflow.com/questions/2019281/load-different-colorscheme-when-using-vimdiff找到了解决方法. (6认同)

Ven*_*oju 17

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

cmp

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

  • 它也可以在Mac OS X上使用. (7认同)
  • `cmp`也可用于(至少某些)Linux发行版. (2认同)

Edu*_*scu 17

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

git diff --no-index --word-diff=color --word-diff-regex=. file1 file2
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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

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

  • 您可能需要包含“--no-index”才能使其实际工作,如主要答案中所述 (2认同)

Mr.*_*ess 8

Python有一个方便的库命名difflib,可能有助于回答你的问题.

下面是两个difflib用于不同python版本的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()))'
Run Code Online (Sandbox Code Playgroud)

这些可能会派上用场,因为它可以更容易随身携带.${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
Run Code Online (Sandbox Code Playgroud)

更可读的版本放在一个独立的文件中.

#!/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)
Run Code Online (Sandbox Code Playgroud)


Chr*_*nce 5

cmp -l file1 file2 | wc
Run Code Online (Sandbox Code Playgroud)

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


Tom*_*ale 5

彩色字符级 diff输出

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

彩色差异截图

#!/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
Run Code Online (Sandbox Code Playgroud)

归功于@reracilesed突出显示的回答

  • 这确实是一个 gvim 问题:)。`命令| gvim -` 会做你想做的事。 (2认同)

Jos*_*hua 5

我还编写了自己的脚本,以使用最长公共子序列算法解决此问题

这样执行

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

结果是带有红色和绿色的html格式。较大的文件会按指数方式花费较长的时间来处理,但这确实可以进行逐字符比较,而无需先逐行检查。


小智 5

ccdiff是完成该任务的便捷专用工具。这是您的示例的样子:

ccdiff 示例输出

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

该软件包包含在Debian 的主存储库中:

ccdiff 是一种彩色差异,它也在更改的行内着色。

所有显示两个文件之间差异的命令行工具都无法显示出明显有用的微小变化。ccdiff 尝试提供diff --color或的外观和感觉colordiff,但将彩色输出的显示从已删除和已添加的彩色行扩展到已更改行中已删除和已添加字符的颜色。

  • @xeruf (**a**) 下载标记的发布版本的 `.tar.gz` 文件;(**b**) 使用 `tar -xzf *.tar.gz` 解压下载的文件;(**c**) 移动提取的文件夹并将其重命名为“/opt/ccdiff”;(**d**) 使用 `ln -s /opt/ccdiff/ccdiff /usr/local/bin/ccdiff` 添加到某些系统文件夹内该文件夹中可执行文件的符号链接;(**e**) 可以用 `ccdiff` 来调用它。 (2认同)

Wil*_*ill 4

Python 的 difflib 可以做到这一点。

该文档包括一个供您使用的示例命令行程序

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