awk 双文件是什么
awk 处理两个文件时有经典套路:利用 NR(累计行号)与 FNR(当前文件行号)在第一个文件里相等这一点,先把小文件读进数组建索引,再逐行处理大文件。这样就能做按列关联,而且输入不需要预先排序。
基本信息
| 用途 | 两文件关联,用于过滤、映射与计数 |
|---|---|
| 语法 | awk 'NR==FNR{建索引; next} {处理}' 小文件 大文件 |
| 原理 | 第一个文件里 NR 与 FNR 相等 |
| 优势 | 无需排序,输出格式完全自由 |
典型使用场景
- 白名单过滤:把允许清单读进内存,再筛大文件里的命中行
- 按列映射:用小文件把代码翻译成名称,补充可读字段
- 分组计数:统计每个用户或每个接口出现的次数
- 字段合并:把两个来源的字段拼成一行输出
- 替代 join:输入无需排序,也能自由控制输出格式
按列映射与过滤
按列映射与过滤
awk 'NR==FNR{a[$1]=$2; next} {print $1, a[$1]}' map.txt data.txt
awk 'NR==FNR{ok[$1]; next} ($1 in ok)' allow.txt access.log
awk -F: 'NR==FNR{name[$3]=$1; next} {print name[$1], $2}' /etc/passwd data.txt分组计数与加权求和
分组计数与加权求和
awk 'NR==FNR{u[$1]; next} ($1 in u){n[$1]++} END{for(k in n) print k, n[k]}' users.txt logs.txt
awk 'NR==FNR{a[$1]=$2; next} {s+=$3*a[$1]} END{print s}' rate.txt usage.txt
awk 'NR==FNR{a[$1]=$2; next} {print $0, a[$1]}' OFS=, map.txt data.txt关键变量
| 变量 | 含义 | 用法 |
|---|---|---|
| NR | 累计已读行数 | 跨文件累加 |
| FNR | 当前文件内的行号 | 每个文件重新计数 |
| NR==FNR | 只在第一个文件成立 | 用于建立索引 |
| next | 跳过后续动作 | 索引阶段读完即跳过 |
| 关联数组 | 充当哈希表 | 用字段做键存放映射 |
比 join 好用在于输入无需排序,比按模式匹配文件更强在于能带出关联字段或做累加。
字段分隔符用 -F 指定,输出分隔符用 -v OFS 指定,处理账号文件或 CSV 时先明确分隔符。
映射数组一对多时只保留最后一个值,会静默丢数据,需要全部值时改成拼接或直接计数。
参数顺序不能颠倒:索引必须来自小文件,把大文件放在前面会让关联数组占用大量内存。
计数结果统一在结束段输出,避免边处理边打印导致结果散落,也更便于排序与二次处理。