Shell按用户统计服务器累计耗时(分钟)及awk分割异常问题
解决按用户汇总服务器累计耗时的AWK问题
我懂你遇到的痛点了——直接用-F:做分隔符的话,会把整行里所有冒号都当成分割标记,结果把用户名和时间的小时部分混在一起,完全偏离了我们想要的效果。
咱们先把需求理清楚:要处理的是每行两列数据(用户名 + HH:MM格式的耗时),最终要按用户汇总总耗时并转换为分钟。正确的思路应该是先按空格拆分每行,把用户名和时间字符串彻底分开,再单独处理时间里的小时和分钟。
直接可用的AWK命令实现
先给你能直接跑的命令,咱们再拆解细节:
awk '{ # 把第二列的时间字符串按冒号拆成小时和分钟,存入数组t split($2, t, ":") # 以用户名为键,累加转换后的分钟数到total数组 total[$1] += t[1] * 60 + t[2] } END { # 遍历数组,输出每个用户的累计总耗时 for (user in total) { print user, total[user] } }' input.txt
为什么这个命令能解决问题?
- 默认空格拆分行:AWK默认以空格作为字段分隔符,所以
$1就是用户名,$2就是完整的时间字符串(比如21:03),这一步就把用户名和时间彻底割开了。 - 单独处理时间字段:用
split($2, t, ":")把时间字符串拆成数组t,t[1]是小时数,t[2]是分钟数,再转成总分钟数t[1]*60 + t[2]。 - 累加与最终输出:用关联数组
total存储每个用户的累计耗时,最后在END块里遍历数组输出所有结果。
用你的示例数据测试
拿你给出的示例数据:
user1 21:03 user2 19:55 user3 20:09 user1 18:57 user1 19:09 user3 21:05 user4 19:57
把这些内容保存到input.txt后,运行上面的命令,会得到如下结果:
user1 3549 user2 1195 user3 2474 user4 1197
你之前的命令为什么出问题?
当你用awk -F: '{print $1}'时,整行被冒号强制分割,比如行user1 21:03会被拆成user1 21($1)和03($2),自然把用户名和小时混在了一起;而print $2时,部分行没有多个冒号,就会出现异常——这都是因为选错了全局分隔符导致的。
内容的提问来源于stack exchange,提问作者Anthino Russo
相关产品推荐
相关产品推荐

