从字符串特定部分的变量中回显

从字符串特定部分的变量中回显

我正在尝试发出一个命令来拥有一个漂亮的git log.假设我有以下内容:

git log --color --pretty=format:"%C(cyan)<%an>" --abbrev-commit

我想做的是创建一个变量%an,根据输出字符串来决定它的颜色。
到目前为止,我已经

USER=$(if [ ! %an = "my own user name" ]
    then
        echo "%C(cyan)<%an>"
    else
        echo %C(bold blue)<%an>
    fi)

然后我将变量放入 git log 中,这样我就有了

git log --color --pretty=format:"$USER" --abbrev-commit

应该做的是,如果提交已经完成,它会以青色打印我的用户名;否则,它将以粗体蓝色打印协作者的用户名。然而,事实并非如此。

我只是想知道是否有人知道我在这里做错了什么?我怀疑这与将变量打印到已经是字符串的环境有关,但我不知道如何修复它。任何帮助表示赞赏!

答案1

您正尝试将 shell 脚本放入 Git 的格式化参数中。当然,这是行不通的。1

  • 有一些 Git 参数实际上接受 shell 脚本,例如git filter-branch;但它们将在相应的手册页中明确指定。

你想要完成的事情实际上可以通过使用外部过滤器来匹配名称,并使用颜色标记它们,而不是通过 Git 来完成ANSI 转义序列

例如,当作者姓名与“乔平均",以青色突出显示名称和尖括号;否则,以粗体蓝色突出显示名称和尖括号。2这两种情况下,保持文本的其他部分不变...

使用Perl 5作为过滤器实现:

git log "--pretty=tformat:%h <%an> %s" | perl -n -e '
chomp;
if(/^(.*)<([^>]*)>(.*)$/) {
    if ($2 eq "Joe Average") {
        print $1."\e[36m<".$2.">\e[39m".$3."\n";
    } else {
        print $1."\e[1m\e[34m<".$2.">\e[39m\e[0m$3\n";
    }
} else {
    print $_."\n";
}'

通过用作sed过滤器来实现(有点 hacky 3)...

git log "--pretty=tformat:%h <%an> %s" | sed '
s/<\(Joe Average\)>/\x1B[36m<\1>\x1B[39m/g;
t matched;
s/<\([^>]*\)>/\x1B[1m\x1B[34m<\1>\x1B[39m\x1B[0m/g;
:matched'

来自测试存储库的常规输出(不带过滤器):

$ git log "--pretty=tformat:%h <%an> %s"
e7f3209 <Joe Average> improving portability
e3ebe74 <Jim Sixpack> adding first working prototype

突出显示的输出(通过任一过滤器):

请注意,即使您更改了输出格式git log,这些过滤器命令仍然有效,前提是:

  • 作者姓名始终包含在 中< >
  • 一行中不超过一位作者。
  • 没有其他东西包含在 中< >

执行您要求的另一种方法是使用不同的and进行两个不同的git log调用,将结果合并在一起,然后按时间戳对它们进行排序;但棘手的部分是确保两个调用的输出不会给出重叠的输出。 (你不能使用,因为这样做会用不同的转义序列标记它们)--author--prettygit loguniq


脚注

  • 1事实上,由于缺乏引用,你的if [ ! %an = "my own user name" ] ... 已经在该USER=行执行了%an将按字面意思进行比较——在 shell 中没有特殊含义);USER="%C(cyan)<%an>"在您调用命令之前就可以有效地完成它git log
  • 2另外,您说您想用青色突出显示您自己的名字,并用蓝色粗体突出显示其他人的名字;但你的原始代码实际上尝试了相反的操作:如果(作者姓名)不是(我自己的用户名),以青色突出显示,否则以粗体蓝色突出显示。我坚持你的描述。
  • 3 \xGNU sed 的扩展,如果您在非 GNU 系统上使用它,您的里程可能会有所不同。

答案2

[ ! %an = "my own user name" ]始终为真,因为%an永远不会等于您的用户名或任何其他用户名:它唯一等于的是%an,因为就 bash 而言,它只是一个文字字符串。它只有特殊含义(“作者姓名”)在git中

可能有一种聪明的方法可以满足您的要求,但我想不出一台 ATM 机。我不认为你可以像你试图做的那样通过混合 bash 和 git 来做到这一点。如果有这样的解决方案,它可能会非常笨拙:你基本上必须在 bash 级别和 git 级别之间进行蹦床,git 循环所有提交,但以某种方式告诉 bash 的作者姓名每个提交,以便 bash 级别可以告诉 git 使用什么颜色。

如果它完成后,我认为这很可能是一个纯粹的 git 解决方案,而不是 bash 和 git 的混合。

答案3

只是为了良好的做法:

变量保存数据。函数保存代码。不要将代码放入变量中!

维基羊毛边缘

相关内容