How to colorize diff on the command line?

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-29 18:32:51
kaji

Man pages for diff suggest no solution for colorization from within itself. Please consider using colordiff. It's a wrapper around diff that produces the same output as diff, except that it augments the output using colored syntax highlighting to increase readability:

diff old new | colordiff

or just:

colordiff old new

Installation:

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

Use Vim:

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

Or better still, VimDiff (or vim -d, which is shorter to type) will show differences between two, three or four files side-by-side.

Examples:

vim -d /path/to/[ab]

vimdiff file1 file2 file3 file4
Lars Baehren

Actually there seems to be yet another option (which I only noticed recently, when running into the problem described above):

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

If you have Git around (which you already might be using anyway), then you will be able to use it for comparison, even if the files themselves are not under version control. If not enabled for you by default, then enabling color support here seems to be considerably easier than some of the previously mentioned workarounds.

diff --color option was added to GNU diffutils 3.4 (2016-08-08)

This is the default diff implementation on most distros, which will soon be getting it.

Ubuntu 18.04 has diffutils 3.6 and therefore has it.

On 3.5 it looks like this:

Tested:

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

Apparently added in commit c0fa19fe92da71404f809aafb5f51cfd99b1bee2 (Mar 2015).

Word-level diff

Like diff-highlight. Not possible it seems, feature request: https://lists.gnu.org/archive/html/diffutils-devel/2017-01/msg00001.html

Related threads:

ydiff does it though, see below.

ydiff side-by-side word level diff

https://github.com/ymattw/ydiff

Is this Nirvana?

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

Outcome:

If the lines are too narrow (default 80 columns), fit to screen with:

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

Contents of the test files:

a

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

b

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

ydiff Git integration

ydiff integrates with Git without any configuration required.

From inside a git repository, instead of git diff, you can do just:

ydiff -s

and instead of git log:

ydiff -ls

See also: How can I get a side-by-side diff when I do "git diff"?

Tested on Ubuntu 16.04, git 2.18.0, ydiff 1.1.

And for those occasions when a yum install colordiff or an apt-get install colordiff is not an option due to some insane constraint beyond your immediate control, or you're just feeling crazy, you can re-invent the wheel with a line of sed:

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

Throw that in a shell script and pipe unified diff output through it.

It makes hunk markers blue and highlights new/old filenames and added/removed lines in green and red background, respectively.1 And it will make trailing space2 changes more readily apparent than colordiff can.


1 Incidentally, the reason for highlighting the filenames the same as the modified lines is that to correctly differentiate between the filenames and the modified lines requires properly parsing the diff format, which is not something to tackle with a regex. Highlighting them the same works "well enough" visually and makes the problem trivial. That said, there are some interesting subtleties.

2 But not trailing tabs. Apparently tabs don't get their background set, at least in my xterm. It does make tab vs space changes stand out a bit though.

You can change the subversion config to use colordiff

~/.subversion/config.diff

 ### 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

via: https://gist.github.com/westonruter/846524

I use grc (Generic Colouriser), which allows you to colour the output of a number of commands including diff.

It is a python script which can be wrapped around any command. So instead of invoking diff file1 file2, you would invoke grc diff file1 file2 to see colourised output. I have aliased diff to grc diff to make it easier.

Tom Hale

Coloured, word-level diff ouput

Here's what you can do with the the below script and diff-highlight:

#!/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 @retracile's answer for the sed highlighting)

jcomeau_ictx

Since wdiff accepts args specifying the string at the beginning and end of both insertions and deletions, you can use ANSI color sequences as those strings:

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

For example, this is the output of comparing two CSV files:

Example from https://www.gnu.org/software/wdiff/manual/html_node/wdiff-Examples.html

Here is another solution that invokes sed to insert the appropriate ANSI escape sequences for colors to show the +, -, and @ lines in red, green, and cyan, respectively.

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

Unlike the other solutions to this question, this solution does not spell out the ANSI escape sequences explicitly. Instead, it invokes the tput setaf and tput sgr0 commands to generate the ANSI escape sequences to set an appropriate color and reset terminal attributes, respectively.

To see the available colors for each argument to tput setaf, use this command:

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

Here is how the output looks:

Here is the evidence that the tput setaf and tput sgr0 commands generate the appropriate ANSI escape sequences:

$ tput setaf 1 | xxd -g1
00000000: 1b 5b 33 31 6d                                   .[31m
$ tput setaf 2 | xxd -g1
00000000: 1b 5b 33 32 6d                                   .[32m
$ tput setaf 6 | xxd -g1
00000000: 1b 5b 33 36 6d                                   .[36m
$ tput sgr0 | xxd -g1
00000000: 1b 28 42 1b 5b 6d                                .(B.[m
Naveen

I would suggest you to give diff-so-fancy a try. I use it during my work and it sure seems great as of now. It comes packed with many options and it's really easy to configure your diffs the way you want.

You can install it by:

sudo npm install -g diff-so-fancy
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!