awk - awk : awk 脚本按条件按列分组
问题描述
我有如下的制表符分隔文件,我正在尝试编写一个 awk 脚本
aaa_log-000592 2 p STARTED 7027691 21.7 a1
aaa_log-000592 28 r STARTED 7027815 21.7 a2
aaa_log-000592 33 p STARTED 7032607 21.7 a3
aaa_log-000592 33 r STARTED 7032607 21.7 a4
aaa_log-000592 43 p STARTED 7025709 21.7 a5
aaa_log-000592 43 r STARTED 7025709 21.7 a6
aaa_log-000595 2 r STARTED 7027691 21.7 a7
aaa_log-000598 28 p STARTED 7027815 21.7 a8
aaa_log-000599 13 p STARTED 7033090 21.7 a9
我正在尝试计算第 3 列(p 或 r)并按第 1 列分组
输出就像
Col1 Count-P Count-R
aaa_log-000592 3 3
aaa_log-000595 0 1
aaa_log-000598 1 0
aaa_log-000599 1 0
我在 awk 中找不到具有 group by 的 IF 条件的示例。
解决方案
awk
(更具体地说,GNU 变体gawk
)具有多维数组,可以使用输入值(包括您的示例中的字符串)进行索引。因此,您可以通过执行以您想要的方式计算值
{
values[$3] = 1 # this line records the values in column three
counts[$1][$3]++ # and this lines counts their frequency
}
第一行不是严格要求的,但它简化了生成输出的过程。
唯一剩下的部分是有一个END
输出表格结果的子句。
END {
# Print column headings
printf "Col1 "
for (v in values) {
printf " Count-%s", v
}
printf "\n"
# Print tabulated results
for (i in counts) {
printf "%-20s", i
for (v in values) {
printf " %d", counts[i][v]
}
printf "\n"
}
}
生成values
数组可以处理第三列的值可能未知的情况(例如,当您的输入中有错误时)。
如果您使用不同的awk
实现(例如,您可能在 macOS 中找到的实现),数组索引可能会有所不同(例如,它们是一维数组,但由逗号分隔的索引列表索引)。这可能会增加一些额外的复杂性,但想法是一样的。
{
files[$1] = 1
values[$3] = 1
counts[$1,$3]++
}
END {
# Print column headings
printf "Col1 "
for (v in values) {
printf " Count-%s", v
}
printf "\n"
# Print tabulated results
for (f in files) {
printf "%-20s", f
for (v in values) {
printf " %d", counts[f,v]
}
printf "\n"
}
}
推荐阅读
- sql-server - 当 JPA 事务通过网络失败时,sql server 会做什么?
- javascript - 循环通过标签并通过 .click 更改 url
- java - Jsoup 检查标签是否存在
- android - Plugin.Geolocator 不可用
- php - 从字符串中获取特定字符串,以模式开头
- docker - 如何在 Docker 之外将 NGINX 反向代理到 proxy_pass 到 docker 容器
- elasticsearch - 无法使用 _delete_by_query 删除 Elasticsearch 中的项目
- javascript - JavaScript 清理 HTML 字符串并删除 ID、类和其他属性
- python - python用外键更新mysql表
- node.js - 如何知道我的 lambda 绑定到的自定义域?