Skip to content

Instantly share code, notes, and snippets.

@apolopena
Last active April 4, 2022 22:29
Show Gist options
  • Save apolopena/69840e229efe13808b426b808560a856 to your computer and use it in GitHub Desktop.
Save apolopena/69840e229efe13808b426b808560a856 to your computer and use it in GitHub Desktop.
Completely colorize a unified diff using sed and without any additional dependencies

The Need

You want fully colorized output for a unified diff of two files or directories (recursively) but you do not want to add any additional dependencies such as colordiff or grc image

The Solution

Pipe output of the unified diff through sed and add colors using ANSI escape sequences based on the pattern of the output.

diff -ur --minimal file1.txt file2.txt | \
sed 's/^[^-+@]/\x1b[38;5;34m&/;s/^-/\x1b[48;5;106m-/;s/^+/\x1b[42m+/;s/^@/\x1b[48;5;130m@/;s/$/\x1b[0m/'

For any of you that are still learning to read sed commands and escape sequences, the rules of parsing the output are as follows:

  1. Any line that does not start with a - or a +, set the foreground color to bright green (ANSI 34)
  2. Any line that starts with a +, set the background color to army green (ANSI 106)
  3. Any line that starts with a -, set the background color to lime green (ANSI 42)
  4. Any line that starts with a @, set the background color to orange (ANSI 172)
  5. Append the end of every line with a reset escape sequence 1b[0m

Examples

Wrap diff in a function and pipe its output through sed

#!/bin/bash
# example1.sh
#
c_uni_diff () {
  diff -ur --minimal "$1" "$2" \
  sed 's/^[^-+@]/\x1b[38;5;34m&/;s/^-/\x1b[48;5;106m-/;s/^+/\x1b[42m+/;s/^@/\x1b[48;5;172m@/;s/$/\x1b[0m/'
}

c_uni_diff "file1.txt" "file2.txt"

Wrap sed in a function that can be piped into or called traditionally.

#!/bin/bash
# example2.sh
#
colorudiff() {
  echo "${1:-$(</dev/stdin)}" \
  | sed 's/^[^-+@]/\x1b[38;5;34m&/;s/^-/\x1b[48;5;106m-/;s/^+/\x1b[42m+/;s/^@/\x1b[48;5;172m@/;s/$/\x1b[0m/'
}
# Pipe in
# diff -ur --minimal file1txt file2.txt | colorudiff
# Or call traditionally
# colorudiff "$(diff -ur --minimal file1txt file2.txt)"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment