如何用Awk从fileA、fileB取值并完成计算与分类输出?
Awk脚本仅输出单行问题解决方案
需求说明
- 基于fileB的数值计算
col3 / col2的结果,除零错误时结果记为0 - 输出时展示fileA中的原始未修改值
- 根据计算结果分类写入文件:
- 结果为0(含除零错误)写入
zero_file - 结果在1-6之间写入
between_file - 结果大于8写入
great_file - 其余情况写入
neither_file
- 结果为0(含除零错误)写入
文件内容
fileA(带单位的原始数据)
col1 col2 col3 col4 1 1K 2K name1 2 0 3K name2 3 1K 20M name3 4 2K 14K name4
fileB(转换为字节的数值数据)
col1 col2 col3 col4 1 1000 2000 name1 2 0 3000 name2 3 1000 20000000 name3 4 2000 14000 name4
期望输出
The name1's rate is 2 (it is calculated from 2K by 1K). The name2's rate is 0 (it is calculated from 3K by 0). The name3's rate is 20000 (it is calculated from 20M by 1K). The name4's rate is 7 (it is calculated from 14K by 2K).
问题描述
已编写单引号、双引号版本的Awk脚本,但仅能输出最后一行结果,无法遍历所有行完成输出。
解决方案
问题原因
大概率是脚本把输出逻辑写在了END{}块中,或者未正确关联两个文件的数据,导致仅处理了最后一条记录。
正确脚本实现
要同时处理两个文件,需先读取fileA的原始值存入数组,再读取fileB计算并输出,同时完成分类写入:
# 先读取fileA,存储原始col2、col3到数组,用col4作为索引 NR == FNR { if (NR > 1) { # 跳过表头 orig_col2[$4] = $2 orig_col3[$4] = $3 } next } # 处理fileB的数据 NR > 1 { # 跳过表头 name = $4 rate = 0 # 处理除零情况,否则计算col3/col2 if ($2 != 0) { rate = $3 / $2 } # 输出期望格式的内容 printf "The %s's rate is %d (it is calculated from %s by %s).\n", name, rate, orig_col3[name], orig_col2[name] # 根据rate分类写入对应文件 if (rate == 0) { print $0 > "zero_file" } else if (rate >= 1 && rate <=6) { print $0 > "between_file" } else if (rate >8) { print $0 > "great_file" } else { print $0 > "neither_file" } }
使用方法
将上述脚本保存为script.awk,在终端执行以下命令:
awk -f script.awk fileA fileB
脚本说明
NR == FNR:仅处理第一个输入文件(fileA),将每行的原始col2、col3以col4(name)为键存入数组- 跳过两个文件的表头,只处理数据行
- 处理fileB时,计算rate(除零则设为0)
- 调用数组中的原始值输出指定格式内容
- 根据rate判断分类,将当前行写入对应文件
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

