如何使用awk处理双输入文件生成缺省补0的用户工具数值交叉表
需求说明
输入文件说明
- input1:存储用户名、工具和对应数值,内容如下:
###### User: a ##### aem 12 aqwt 24 ##### User: B ##### aem 34 bwem 52 dd 12 ##### User: C ##### aem 11 aqwt 2 dd 1 #####
- input2:工具列表,内容如下:
aem aqwt bwem dd
期望输出
生成用户与工具的对应数值表,用户无对应工具数值时填充0,样式如下:
Tool a B C aem 12 34 11 aqwt 24 0 2 bwem 0 52 0 dd 0 12 1
现有问题
当前编写的awk脚本如下:
awk 'NR==FNR{a[$1];next} ($1 in a); {print $2} !($1 in a); {print "0"}' input2 input1
运行后存在两个问题:
- 会输出注释行(以#开头的行)的内容
- 结果没有按要求的列格式排列
解决方案
修改后的awk脚本逻辑如下:
- 优先读取input2,存储所有工具名称到工具列表
- 读取input1时跳过所有以
#开头的注释行 - 匹配到
User:开头的行时,记录当前用户名并存入用户列表 - 存储每个用户对应工具的数值到二维数组
- 所有内容读取完成后,先输出表头,再按工具遍历输出每行数值,无对应值时填充0
最终可运行脚本如下:
awk ' # 读取input2存储工具列表 NR == FNR { tools[++tool_cnt] = $1 tool_map[$1] = 1 next } # 跳过#开头的注释行 /^#/ { next } # 匹配用户行记录当前用户 /^User: / { cur_user = $2 users[++user_cnt] = cur_user next } # 存储当前用户对应工具的数值 $1 in tool_map { val[cur_user][$1] = $2 } # 处理完成后格式化输出结果 END { # 输出表头 printf "%-6s", "Tool" for (i=1; i<=user_cnt; i++) { printf "%-4s", users[i] } print "" # 按工具遍历输出每行数据 for (i=1; i<=tool_cnt; i++) { t = tools[i] printf "%-6s", t for (j=1; j<=user_cnt; j++) { u = users[j] printf "%-4d", (val[u][t] ? val[u][t] : 0) } print "" } } ' input2 input1
脚本中的%-6s、%-4d为列对齐控制参数,可根据实际内容长度调整。
内容的提问来源于stack exchange,提问作者masifq
相关产品推荐
相关产品推荐

