In my day-to-day role as a software engineer I share with my peers unified-differences derived from the diff(1) command. For example:
$ diff -u old new --- old Wed Oct 29 14:36:47 2008 +++ new Wed Oct 29 14:36:56 2008 @@ -1,9 +1,15 @@ I really -should +ought provide better examples. -Or at least use some of my daughters poetry +Mary +had +a +little +lamb, + +Or perhaps use some of my daughters poetry. $
Where differences occur a line listing the original line number followed by the new line numbers are displayed which is followed by the changes. Lines removed from "new" are marked with a "-" at the beginning while lines added to "new" are marked with a "+". In the example its quite easy to see that line three has been removed and replaced. However it is sometimes not so obvious, the line numbers get a little confusing in ensuing conversation.
So I put together a little nawk script to display the line numbers in-line as well:
$ diff -u old new | udiffn
--- old Wed Oct 29 14:36:47 2008
+++ new Wed Oct 29 14:36:56 2008
Old New @@ -1,9 +1,15 @@
1 1 I
2 2 really
3 -should
3 +ought
4 4 provide
5 5 better
6 6 examples.
7 7
8 -Or at least use some of my daughters poetry
8 +Mary
9 +had
10 +a
11 +little
12 +lamb,
13 +
14 +Or perhaps use some of my daughters poetry.
9 15
Ideally diff(1) would have an option to provide this output but in the mean time this little tool will suffice:
$ cat ~/tools/sh/udiffn
#!/bin/nawk -f
# Add line numbers to unified diff output: diff -u old new | udiffn
/^No differences encountered/ || # No exit as intended as a pipe
/^$/ || # Blank lines
/^(\-\-\-|\+\+\+)/ {print; next;} # diff Headers
/^@@ [-+][0-9]*,[0-9]* [+-][0-9]*,[0-9]* @@/ { # Start of difference block
i=split(substr($2,2), o, ","); # old start line in o[1]
j=split(substr($3,2), n, ","); # new start line in n[1]
l=length(n[1])+1; # Numeric field length
if (l <= 4 ) l = 4;
printf("%*s %*s %s\n", l, "Old", l, "New", $0);
next;
}
/^ / {printf("%*s %*d %s\n", l, o[1]++, l, n[1]++, $0); next;}
/^\+/ {printf("%*s %*d %s\n", l, " ", l, n[1]++, $0); next;}
/^\-/ {printf("%*d %*s %s\n", l, o[1]++, l, " ", $0); next;}
/^Index: / {print; next} # patch/wx header
/^diff -r/ {print; next} # Mercurial header
# Everything else is unexpected.
{print "Er!",NR,$0;}

