关于unix:如何在命令行上对diff进行着色?

How to colorize diff on the command line?

当我有差异时,我怎样才能给它上色,使它看起来很好?我希望它用于命令行,所以请不要使用GUI解决方案。


diff的手册页不建议从内部着色。请考虑使用colordiff。它是一个围绕diff的包装器,产生与diff相同的输出,只是它使用彩色语法突出显示来增强输出,以提高可读性:

1
diff old new | colordiff

或者只是:

1
colordiff old new

安装:

  • Ubuntu/Debian:sudo apt-get install colordiff
  • OS X:brew install colordiffport install colordiff


使用VIM:

1
diff /path/to/a /path/to/b | vim -R -

或者更好的是,vimdiff(或vim -d,它比type短)将显示两个、三个或四个文件并排的差异。

示例:

1
vim -d /path/to/[ab]

1
vimdiff file1 file2 file3 file4


实际上,似乎还有另一种选择(我最近才注意到,当遇到上述问题时):

1
2
3
git diff --no-index <file1> <file2>
# output to console instead of opening a pager
git --no-pager diff --no-index <file1> <file2>

如果您有Git(不管怎样,您可能已经在使用它),那么您将能够使用它进行比较,即使文件本身不受版本控制。如果默认情况下没有为您启用,那么在这里启用颜色支持似乎比前面提到的一些解决方法要容易得多。


GNU Diffutils 3.4(2016-08-08)增加了diff --color选项。

这是大多数发行版上默认的diff实现,很快就会得到它。

Ubuntu 18.04有diffutils3.6,因此也有。

在3.5中,它看起来是这样的:

enter image description here

已测试:

1
2
3
diff --color -u \
  <(seq 6 | sed 's/$/ a/') \
  <(seq 8 | grep -Ev '^(2|3)$' | sed 's/$/ a/')

显然加入了Commit c0fa19fe92da71404f809aafb5f51cfd99b1bee2(2015年3月)。

字级差异

diff-highlight一样。似乎不可能,功能请求:https://lists.gnu.org/archive/html/diffutils-devel/2017-01/msg0001.html

相关线程:

  • 使用"diff"(或其他任何方法)获取文本文件之间的字符级别diff
  • https://unix.stackexchange.com/questions/11128/diff-within-a-line
  • https://superuser.com/questions/496415/using-diff-on-a-long-one-line-file

不过,ydiff做到了,见下文。

ydiff并排字级差异

网址:https://github.com/ymattw/ydiff

这是涅盘吗?

1
2
python3 -m pip install --user ydiff
diff -u a b | ydiff -s

结果:

氧化镁

如果行太窄(默认为80列),则适合屏幕:

1
diff -u a b | ydiff -w 0 -s

测试文件的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5 the original line the original line the original line the original line
6
7
8
9
10
11
12
13
14
15 the original line the original line the original line the original line
16
17
18
19
20

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5 the original line teh original line the original line the original line
6
7
8
9
10
11
12
13
14
15 the original line the original line the original line the origlnal line
16
17
18
19
20

ydiffgit集成

ydiff与git集成,无需任何配置。

从Git存储库中,您可以执行以下操作,而不是从git diff

1
ydiff -s

而不是git log

1
ydiff -ls

另请参见:当我执行"git diff"时,如何获得并排diff?

在Ubuntu 16.04、Git 2.18.0、YDiff 1.1上测试。


在那些情况下,当一个yum install colordiff或一个apt-get install colordiff由于一些你无法立即控制的疯狂的限制而不是一个选择,或者你只是感觉疯狂时,你可以用一条SED线重新发明轮子:

1
sed 's/^-/\x1b[41m-/;s/^+/\x1b[42m+/;s/^@/\x1b[34m@/;s/$/\x1b[0m/'

将其放入shell脚本,并通过它传输统一的diff输出。

它使大块标记变蓝,并分别突出新/旧文件名和在绿色和红色背景中添加/删除的行。1,它将使尾部空格2的变化比colordiff更明显。

1顺便说一下,突出显示与修改行相同的文件名的原因是为了正确区分文件名和修改行,需要正确分析diff格式,这不是regex要解决的问题。将它们突出显示在视觉上"足够好"并使问题变得微不足道。也就是说,有一些有趣的微妙之处。

2个,但不是尾随标签。显然,选项卡没有设置背景,至少在我的xterm中没有。不过,这确实让标签和空间的变化有点突出。


您可以将Subversion配置更改为使用ColorDiff

~/.Subversion/配置差异

1
2
3
4
5
 ### Set diff-cmd to the absolute path of your 'diff' program.
 ###   This will override the compile-time default, which is to use
 ###   Subversion's internal diff implementation.
-# diff-cmd = diff_program (diff, gdiff, etc.)
+diff-cmd = colordiff

通过:https://gist.github.com/westonruter/846524


彩色,字级diff输出

下面是您可以使用以下脚本和diff highlight执行的操作:

Coloured diff screenshot

1
2
3
4
5
6
7
#!/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

(credit to@retraccile's answer for the sedhighlighting)


我使用grc(通用色器),它允许您对包括diff在内的许多命令的输出进行着色。

它是一个python脚本,可以环绕任何命令。因此,您不需要调用diff file1 file2,而是调用grc diff file1 file2来查看彩色输出。我把diff化名为grc diff,以使其更简单。


由于wdiff接受在插入和删除的开头和结尾指定字符串的参数,因此可以使用ansi颜色序列作为这些字符串:

1
wdiff -n -w $'\033[30;41m' -x $'\033[0m' -y $'\033[30;42m' -z $'\033[0m' file1 file2

例如,这是比较两个csv文件的输出:

氧化镁

示例来自https://www.gnu.org/software/wdiff/manual/html_node/wdiff-examples.html


这里还有另一种解决方案,它调用sed插入颜色的适当的ansi转义序列,分别以红色、绿色和青色显示+-@行。

1
diff -u old new | sed"s/^-/$(tput setaf 1)&/; s/^+/$(tput setaf 2)&/; s/^@/$(tput setaf 6)&/; s/$/$(tput sgr0)/"

与此问题的其他解决方案不同,此解决方案不会显式拼写出ANSI转义序列。相反,它调用tput setaftput sgr0命令来生成ansi转义序列,分别设置适当的颜色和重置终端属性。

要查看tput setaf的每个参数的可用颜色,请使用以下命令:

1
for i in {0..255}; do tput setaf $i; printf %4d $i; done; tput sgr0; echo

以下是输出的外观:

氧化镁

这里有证据表明,tput setaftput sgr0命令生成了适当的ansi转义序列:

1
2
$ tput setaf 1 | xxd -g1
00000000: 1b 5b 33 31 6d                                   .[31m

1
2
$ tput setaf 2 | xxd -g1
00000000: 1b 5b 33 32 6d                                   .[32m

1
2
$ tput setaf 6 | xxd -g1
00000000: 1b 5b 33 36 6d                                   .[36m

1
2
$ tput sgr0 | xxd -g1
00000000: 1b 28 42 1b 5b 6d                                .(B.[m


我建议你试一试。我在工作中使用它,到目前为止它看起来确实很棒。它包含许多选项,并且很容易按照您想要的方式配置差异。

您可以通过以下方式安装:

1
sudo npm install -g diff-so-fancy