1/3:错误修复
@Inian was correct:我只需要在参数之间使用逗号。我已经投入了工作(自发布此问题以来可能长达约 20~30 小时)并且我现在在使用 awk 的基础知识方面相当不错。我学到了很多东西。
为了回答这个问题,这是我在@Inian 根据他的反馈发布他的答案后立即提出的解决方案。要关注的关键部分是printf 调用。请注意,我在格式字符串和之后的每个参数之间添加了逗号。正如他所说,这就是解决办法。
重点关注的部分:
printf "-%+4s :%s\n", left++, line
printf "+%+4s :%s\n", right++, line
printf " %+4s,%+4s:%s\n", left++, right++, line
上下文中的全部内容:
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}'
这是我通过将上述脚本复制并粘贴到我的终端中得到的一些示例输出。如果您想完全复制此内容,请转到 git clone my dotfiles repo 并运行 git checkout 4386b089f163d9d5ff26d277b53830e54095021c。然后,将上述脚本复制并粘贴到您的终端中。输出看起来相当不错。左边的数字和事物的对齐现在看起来不错:
$ 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: '
这是一个显示漂亮颜色输出的屏幕截图:
原始脚本,如下所示:
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}'
产生看起来很糟糕(相比之下)、未对齐的输出:
$ 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): '
截图:
2/3:使数字也着色:
回答我问题的第二部分:
此外,数字和 +/- 符号应分别为绿色和红色,就像在正常的 git diff 输出中一样。
然后我将红色 (\033[31m) 和绿色 (\033[32m) 的一些 ANSI 颜色代码添加到如下所示的倒数第三行和倒数第二行:
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}'
并得到了这个更好看的输出。注意最左边的数字现在也被着色了:
3/3:最后:
然后:
- 对上面的代码进行了几天的剖析
- 疯狂地学习
awk
- 扔掉上面的整个代码,因为它
- 无法阅读且格式严重
- 做了一些没有任何意义且不需要的非常奇怪的事情,并且
- 没有处理任何边缘情况或自定义 git diff 颜色
- 保留了绝对巧妙和完美的非常好的部分,并且
- 写了this really nice and full implementation of
git diffn,其中:
- 处理我能想到的所有边缘情况
- 充当
git diff 的直接替代品
- 处理所有可能的颜色和文本格式(据我所知),并且
- 无论有没有颜色,都能产生非常好的输出
请参阅此处以获取git diffn 信息和安装说明:Git diff with line numbers (Git log with line numbers)
结束。