You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Awk合并git status与git diff --stat输出并保留颜色

优雅合并git status -sb与git diff --stat输出的Awk方案

需求说明

需要将git status -sb的文件状态标识,与git diff --stat的行变更统计合并输出,同时满足:

  • 保留git输出的ANSI颜色
  • 当只有新增文件时(此时git diff --stat无输出),仍能正常显示所有状态行

示例输入:

  • git status -sb输出:
## main
M a
?? b
  • git --no-pager diff --stat | head -n-1输出:
a | 2 ++

期望输出:

## main
 M a | 2 ++
?? b

解决方案

使用以下Awk命令可以优雅实现需求:

git status -sb | awk '
    BEGIN {
        # 预读取diff统计到关联数组,保留ANSI颜色
        while ("git --no-pager diff --stat | head -n-1" | getline line) {
            split(line, parts, " | ")
            file_stats[parts[1]] = substr(line, index(line, " | "))
        }
        # 关闭管道避免资源泄漏
        close("git --no-pager diff --stat | head -n-1")
    }
    # 直接打印分支信息行
    NR == 1 { print; next }
    # 处理状态行
    {
        # 分离状态标识与文件名,兼容"?? b"、"M  a.txt"等格式
        if (length($0) >= 2 && substr($0,2,1) ~ /[?MADRCU ]/) {
            status = substr($0, 1, 2)
            file = substr($0, 3)
        } else {
            status = substr($0, 1, 1)
            file = substr($0, 2)
        }
        # 清除文件名前后的空白字符
        gsub(/^[[:space:]]+|[[:space:]]+$/, "", file)
        # 拼接输出:状态+文件名+统计信息(存在则追加)
        printf "%s%s%s\n", status, file, (file in file_stats) ? file_stats[file] : ""
    }
'

关键细节解释

  1. 保留ANSI颜色:通过在Awk的BEGIN块中直接读取git diff --stat的原始输出(包含颜色转义序列),存入数组后直接复用,不会过滤颜色码。只要git本身开启了颜色输出(默认开启),就能完整保留。
  2. 处理空输出场景:当只有新增文件时,git diff --stat无输出,此时file_stats数组为空,Awk会直接输出git status -sb的状态行,不会丢失任何内容。
  3. 兼容多种状态格式:通过判断状态标识的格式,兼容??(未跟踪)、M(修改)、A(新增)等不同状态的输出格式,同时处理文件名前后的空白字符,避免匹配失败。

测试场景验证

  • 混合修改与新增:输出与期望一致,修改文件会拼接行统计,新增文件直接显示状态。
  • 仅新增文件:正常输出所有未跟踪文件的状态行,无丢失。
  • 仅修改文件:正确拼接状态标识与行统计,颜色保留完整。

内容的提问来源于stack exchange,提问作者Marslo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 00:08:17