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
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:
- Any line that does not start with a
-
or a+
, set the foreground color to bright green (ANSI 34) - Any line that starts with a
+
, set the background color to army green (ANSI 106) - Any line that starts with a
-
, set the background color to lime green (ANSI 42) - Any line that starts with a
@
, set the background color to orange (ANSI 172) - Append the end of every line with a reset escape sequence
1b[0m
Wrap
diff
in a function and pipe its output throughsed
#!/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)"