使用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] : "" } '
关键细节解释
- 保留ANSI颜色:通过在Awk的BEGIN块中直接读取
git diff --stat的原始输出(包含颜色转义序列),存入数组后直接复用,不会过滤颜色码。只要git本身开启了颜色输出(默认开启),就能完整保留。 - 处理空输出场景:当只有新增文件时,
git diff --stat无输出,此时file_stats数组为空,Awk会直接输出git status -sb的状态行,不会丢失任何内容。 - 兼容多种状态格式:通过判断状态标识的格式,兼容
??(未跟踪)、M(修改)、A(新增)等不同状态的输出格式,同时处理文件名前后的空白字符,避免匹配失败。
测试场景验证
- 混合修改与新增:输出与期望一致,修改文件会拼接行统计,新增文件直接显示状态。
- 仅新增文件:正常输出所有未跟踪文件的状态行,无丢失。
- 仅修改文件:正确拼接状态标识与行统计,颜色保留完整。
内容的提问来源于stack exchange,提问作者Marslo
相关产品推荐
相关产品推荐

