I obtained this code sample from someone else here:
git diff --color=always | \\
gawk \'{bare=$0;gsub(\"\\033[[][0-9]*m\",\"\",bare)};\\
match(ba
@Inian was correct: I just needed commas between arguments. I've put in the work (perhaps as much as ~20~30 hrs since posting this question) and I'm pretty decent at the basics of using awk
now. I've learned a ton.
For the sake of answering this question, here's the solution I came up with right after @Inian posted his answer, based on his feedback. The key parts to focus in on are the printf
calls. Notice I've added commas in between the format string and each argument thereafter. As he said, that's the fix.
Parts to focus on:
printf "-%+4s :%s\n", left++, line
printf "+%+4s :%s\n", right++, line
printf " %+4s,%+4s:%s\n", left++, right++, line
Whole thing in context:
git diff HEAD~..HEAD --color=always | \
gawk '{bare=$0;gsub("\033[[][0-9]*m","",bare)};\
match(bare,"^@@ -([0-9]+),[0-9]+ [+]([0-9]+),[0-9]+ @@",a){left=a[1];right=a[2];next};\
bare ~ /^(---|\+\+\+|[^-+ ])/{print;next};\
{line=gensub("^(\033[[][0-9]*m)?(.)","\\2\\1",1,$0)};\
bare~/^-/{printf "-%+4s :%s\n", left++, line;next};\
bare~/^[+]/{printf "+%+4s :%s\n", right++, line;next};\
{printf " %+4s,%+4s:%s\n", left++, right++, line;next}'
Here's some sample output I get just by copying and pasting the above script into my terminal. If you'd like to duplicate this exactly, go git clone
my dotfiles repo and run git checkout 4386b089f163d9d5ff26d277b53830e54095021c
. Then, copy and paste the above script into your terminal. The output looks pretty good. The alignment of the numbers and things on the left now looks nice:
$ git diff HEAD~..HEAD --color=always | \
> gawk '{bare=$0;gsub("\033[[][0-9]*m","",bare)};\
> match(bare,"^@@ -([0-9]+),[0-9]+ [+]([0-9]+),[0-9]+ @@",a){left=a[1];right=a[2];next};\
> bare ~ /^(---|\+\+\+|[^-+ ])/{print;next};\
> {line=gensub("^(\033[[][0-9]*m)?(.)","\\2\\1",1,$0)};\
> bare~/^-/{printf "-%+4s :%s\n", left++, line;next};\
> bare~/^[+]/{printf "+%+4s :%s\n", right++, line;next};\
> {printf " %+4s,%+4s:%s\n", left++, right++, line;next}'
diff --git a/useful_scripts/git-diffn.sh b/useful_scripts/git-diffn.sh
index 22c74e2..cf8ba08 100755
--- a/useful_scripts/git-diffn.sh
+++ b/useful_scripts/git-diffn.sh
49, 49: # 4. `git-gs_diffn`
50, 50: # 3. `gs_git-diffn`
51, 51:
+ 52 :+# FUTURE WORK:
+ 53 :+# 1. Make work with standard awk?
+ 54 :+# This has been tested on Linux Ubuntu 18.04. If anyone can't get this working on their system,
+ 55 :+# such as in the git bash terminal that comes with Git for Windows, or on MacOS, due to
+ 56 :+# compatibility probems with `gawk`, I can rewrite the few places relying on `gawk` extensions
+ 57 :+# to just use basic awk instead. That should solve any compatibility problems, but there's no
+ 58 :+# sense in doing it if there's no need. If I ever need to do this in the future though, I'm
+ 59 :+# going to need this trick to obtain a substring using standard awk:
+ 60 :+# https://stackoverflow.com/questions/5536018/how-to-print-matched-regex-pattern-using-awk/5536342#5536342
+ 61 :+# 1. Also, look into this option in gawk for testing said compatibility:
+ 62 :+# 1. `--lint` - https://www.gnu.org/software/gawk/manual/html_node/Options.html
+ 63 :+# 1. `--traditional` and `--posix` - https://www.gnu.org/software/gawk/manual/html_node/Compatibility-Mode.html
+ 64 :+# 1. Currently, `--lint` is telling me that the 3rd argument to `match()` (ie: the array
+ 65 :+# parameter) is a gawk extension.
+ 66 :+
52, 67: # References:
53, 68: # 1. This script borrows from @PFudd's script here:
54, 69: # https://stackoverflow.com/questions/24455377/git-diff-with-line-numbers-git-log-with-line-numbers/33249416#33249416
133, 148: # "41", "42", etc. codes is this:
134, 149: # ^(\033\[(([0-9]{1,2};?){1,10})m)?
135, 150:
+ 151 :+# Be sure to place all args (`"$@"`) AFTER `--color=always` so that if the user passes in
+ 152 :+# `--color=never` or `--no-color` they will override my `--color=always` here, since later
+ 153 :+# options override earlier ones.
136, 154: git diff --color=always "$@" | \
137, 155: gawk \
138, 156: '
Here's a screenshot to show the nice color output:
The original script, shown here:
git diff HEAD~..HEAD --color=always | \
gawk '{bare=$0;gsub("\033[[][0-9]*m","",bare)};\
match(bare,"^@@ -([0-9]+),[0-9]+ [+]([0-9]+),[0-9]+ @@",a){left=a[1];right=a[2];next};\
bare ~ /^(---|\+\+\+|[^-+ ])/{print;next};\
{line=gensub("^(\033[[][0-9]*m)?(.)","\\2\\1",1,$0)};\
bare~/^-/{print "-"left++ ":" line;next};\
bare~/^[+]/{print "+"right++ ":" line;next};\
{print "("left++","right++"):"line;next}'
produces pretty awful-looking (in comparison), unaligned output:
$ git diff HEAD~..HEAD --color=always | \
> gawk '{bare=$0;gsub("\033[[][0-9]*m","",bare)};\
> match(bare,"^@@ -([0-9]+),[0-9]+ [+]([0-9]+),[0-9]+ @@",a){left=a[1];right=a[2];next};\
> bare ~ /^(---|\+\+\+|[^-+ ])/{print;next};\
> {line=gensub("^(\033[[][0-9]*m)?(.)","\\2\\1",1,$0)};\
> bare~/^-/{print "-"left++ ":" line;next};\
> bare~/^[+]/{print "+"right++ ":" line;next};\
> {print "("left++","right++"):"line;next}'
diff --git a/useful_scripts/git-diffn.sh b/useful_scripts/git-diffn.sh
index 22c74e2..cf8ba08 100755
--- a/useful_scripts/git-diffn.sh
+++ b/useful_scripts/git-diffn.sh
(49,49): # 4. `git-gs_diffn`
(50,50): # 3. `gs_git-diffn`
(51,51):
+52:+# FUTURE WORK:
+53:+# 1. Make work with standard awk?
+54:+# This has been tested on Linux Ubuntu 18.04. If anyone can't get this working on their system,
+55:+# such as in the git bash terminal that comes with Git for Windows, or on MacOS, due to
+56:+# compatibility probems with `gawk`, I can rewrite the few places relying on `gawk` extensions
+57:+# to just use basic awk instead. That should solve any compatibility problems, but there's no
+58:+# sense in doing it if there's no need. If I ever need to do this in the future though, I'm
+59:+# going to need this trick to obtain a substring using standard awk:
+60:+# https://stackoverflow.com/questions/5536018/how-to-print-matched-regex-pattern-using-awk/5536342#5536342
+61:+# 1. Also, look into this option in gawk for testing said compatibility:
+62:+# 1. `--lint` - https://www.gnu.org/software/gawk/manual/html_node/Options.html
+63:+# 1. `--traditional` and `--posix` - https://www.gnu.org/software/gawk/manual/html_node/Compatibility-Mode.html
+64:+# 1. Currently, `--lint` is telling me that the 3rd argument to `match()` (ie: the array
+65:+# parameter) is a gawk extension.
+66:+
(52,67): # References:
(53,68): # 1. This script borrows from @PFudd's script here:
(54,69): # https://stackoverflow.com/questions/24455377/git-diff-with-line-numbers-git-log-with-line-numbers/33249416#33249416
(133,148): # "41", "42", etc. codes is this:
(134,149): # ^(\033\[(([0-9]{1,2};?){1,10})m)?
(135,150):
+151:+# Be sure to place all args (`"$@"`) AFTER `--color=always` so that if the user passes in
+152:+# `--color=never` or `--no-color` they will override my `--color=always` here, since later
+153:+# options override earlier ones.
(136,154): git diff --color=always "$@" | \
(137,155): gawk \
(138,156): '
Screenshot:
To answer the 2nd part of my question:
Additionally, the numbers and +/- signs should be green and red, respectively, like in normal git diff output.
I then added some ANSI color codes for red (\033[31m
) and green (\033[32m
) to the 3rd-from-last and 2nd-from-last lines shown below:
git diff HEAD~..HEAD --color=always | \
gawk '{bare=$0;gsub("\033[[][0-9]*m","",bare)};\
match(bare,"^@@ -([0-9]+),[0-9]+ [+]([0-9]+),[0-9]+ @@",a){left=a[1];right=a[2];next};\
bare ~ /^(---|\+\+\+|[^-+ ])/{print;next};\
{line=gensub("^(\033[[][0-9]*m)?(.)","\\2\\1",1,$0)};\
bare~/^-/{printf "\033[31m-%+4s :%s\n", left++, line;next};\
bare~/^[+]/{printf "\033[32m+%+4s :%s\n", right++, line;next};\
{printf " %+4s,%+4s:%s\n", left++, right++, line;next}'
and got this nicer-looking output. Notice the numbers at the far left are now colored too:
I then:
awk
like crazygit diff
See here for git diffn
info & installation instructions: Git diff with line numbers (Git log with line numbers)
The end.
It should be a minor typo (most likely) because printf()
in awk
expects a ,
after the format specifiers
printf "-%-8s:", left++ line
# ^^^