32

I've been using git diff, which produces colored output. However, I now find I need to use ordinary diff for something, and it's producing a lot of output that is hard to read because of the lack of colors. How do I make diff produce a readable, colored output? Ideally while piping it to less, for easy review of large files.

30

diff cannot output colors, you need another program, such as colordiff for that. Colors in the terminal are printed via ANSI escape codes which less does not interpret by default. To get less to correctly show colors, you need the -r, or even better, -R switch:

colordiff -- "$file1" "$file2" | less -R

From man less:

   -R or --RAW-CONTROL-CHARS
          Like -r, but only ANSI  "color"  escape  sequences  are
          output in "raw" form.  Unlike -r, the screen appearance
          is maintained correctly in most  cases.   ANSI  "color"
          escape sequences are sequences of the form:

               ESC [ ... m

          where  the  "..."  is  zero or more color specification
          characters For the purpose of keeping track  of  screen
          appearance,  ANSI color escape sequences are assumed to
          not move the cursor.  You  can  make  less  think  that
          characters  other  than  "m"  can end ANSI color escape
          sequences by setting the environment  variable  LESSAN‐
          SIENDCHARS  to  the  list of characters which can end a
          color escape sequence.  And you  can  make  less  think
          that characters other than the standard ones may appear
          between the ESC and the m by  setting  the  environment
          variable  LESSANSIMIDCHARS  to  the  list of characters
          which can appear.

Alternatively, you can use more which will display colors correctly by default.


If you cannot install external programs, you should be able to get the same output using a more manual approach:

diff a b | 
   perl -lpe 'if(/^</){$_ = "\e[1;31m$_\e[0m"} 
              elsif(/^>/){$_ = "\e[1;34m$_\e[0m"}'
10

The other answers here might be out of date. As of coreutils 3.5 diff can indeed produce colored output which is turned off by default when the stdout is not a console.

From the man page:

--color[=WHEN]
colorize the output; WHEN can be never, always, or auto (the default)

To force color output when stdout is a pipe diff --color=always -- "$file1" "$file2" | less -R should work.

7

To pipe colored diff to less:

diff $file1 $file2 | colordiff | less -r

To make it more readable, by limiting it to a single screen:

diff -uw $file1 $file2 | colordiff | less -r

And, to cause less not to display if there is only one screens worth of content:

diff -uw $file1 $file2 | tee /dev/stderr | colordiff | less -r -F

The -F causes less to close immediately if there is less than one screens worht of content, the pipe to stderr is because when less closes you lose the output - by piping to stderr, it gets output even if less does not display.

An alternative (and, I think, better) way, is to just use -X to prevent less clearing the screen:

diff -uw $file1 $file2 | colordiff | less -r -X -F

This works well for me, but might be specific to bash. colordiff is not a built-in, but is easily installed.

  • 2
    The only command he needs is less -r – sendmoreinfo May 17 '13 at 16:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.