最近的工作需要做很多性能优化,会需要打 log,然后用 awk 做一些统计分析。而这些分析也需要写到文档里,我希望这些分析结果尽量是格式优雅的,所以经常要在 awk 输出的时候做一些对齐。

实际上我要的就是表头与数据项对齐,比如这样:

type  times  objcnt  cost(us)  avgcost(us)  备注
1     3900   1       33.430    33.430       xxx             
5     3901   696     2990.278  4.296        xxx             
9     3901   1       10.181    10.181       xxx             
10    3901   1       5.675     5.675        xxx          
12    3871   96      343.067   3.578        xxx           
14    3901   410     1351.222  3.296        xxx           

以前我没怎么好好研究过这个问题,就经常搞右对齐,然后手动增加一些空格,让结果最终看起来是比较对齐的。

但这周我发现这样很费劲,就花时间琢磨了一下,终于悟到了最佳做法:全部做成左对齐的,数据项预留宽度与表头字段宽度保持一致,空格也保持一致。

比如这样的数据:

[INFO ][32843][09:20:15.982] [LUA] [somefile] checkxxx, time_now = 1743556815956 idx = 0 some_type =  5 objCnt = 696 totalCost = 11530 avg_cost = 16.566 
[INFO ][32843][09:20:15.982] [LUA] [somefile] checkxxx, time_now = 1743556815956 idx = 0 some_type =  9 objCnt =   1 totalCost =    7 avg_cost = 7.000 
[INFO ][32843][09:20:15.982] [LUA] [somefile] checkxxx, time_now = 1743556815956 idx = 0 some_type = 10 objCnt =   1 totalCost =    6 avg_cost = 6.000 
[INFO ][32843][09:20:15.984] [LUA] [somefile] checkxxx, time_now = 1743556815956 idx = 0 some_type = 14 objCnt = 410 totalCost = 1503 avg_cost = 3.666 
[INFO ][32843][09:20:15.984] [LUA] [somefile] checkxxx, time_now = 1743556815956 idx = 0 some_type = 16 objCnt =  35 totalCost =  140 avg_cost = 4.000 

写这样的脚本:

#!/bin/bash

echo "type  times  objcnt  cost(us)  avgcost(us)  备注"
cat aoiobj-time.txt | grep "some_type =  1" | awk '{totalcost += $20; avgcost += $23; objcnt += $17; times++} END {printf("%-4d  %-5d  %-6d  %-8.3f  %-11.3f  %-15s\n", 1, times, objcnt/times, totalcost/times, avgcost/times, "xxx")}'
cat aoiobj-time.txt | grep "some_type =  5" | awk '{totalcost += $20; avgcost += $23; objcnt += $17; times++} END {printf("%-4d  %-5d  %-6d  %-8.3f  %-11.3f  %-15s\n", 5, times, objcnt/times, totalcost/times, avgcost/times, "xxx")}'

表头是 type objcnt cost(us) avgcost(us) 备注,那么awk 输出用这样的格式 %-4d %-6d %-8.3f %-11.3f %-15s\n,就可以让数据项与表头对齐了。

在 awk 中, %-4d 其中 - 表示左对齐, 4 表示输出宽度为 4, d 表示整数。

type 的宽度是 4,那么数据项用 %-4d,而 objcnt 的宽度是 6,那么数据项项 %-6d

其他场景下,也都用这种方式就行了,不同语言的格式化输出基本上都是类似的。

以上。