如何按行求和指定列并计算占比及Project_Name级平均占比
问题描述
我有一个多列数据文件,已经实现每行$3与$NF的求和并生成Cold-Data列,但遇到两个问题:
- 无法计算
Cold-Data/PhysicalBlocks*100得到PercentageRatio并添加%符号; - 希望按
Project_Name分组计算平均占比PercentageRatioAvg。
我尝试的bash脚本如下:
#!/bin/bash printf '%s %s %s %s %s %s %s %s\n' Project_Name Volume_Name InactiveTier PhysicalBlocks SSDtier GRIDtier Cold-Data ratio gawk 'FNR > 1 { print $1,$2,$3,$4,$5,$6,$3+$NF, $8 = $7/$4}1' ttk
当前输出存在重复行,且PercentageRatio列显示为0,未达到预期效果。相关数据如下:
原始数据
Project_Name Volume_Name InactiveTier PhysicalBlocks SSDtier GRIDtier cayman fsx3008_cayman 80289 85639 85702 0 cayman fsx3008_caymans 0 72802 3516 69553 cch fsx3008_cch 0 73116 3400 69847 test fsx3008_test 0 3698 1193 2627 test fsx3008_test1 0 2 26 0 dtsoio fsx3008_dts1 74068 89596 89740 0 dtsoio fsx3008_dts2 0 496843 188528 314897 arns fsx3008_arns1 0 852 682 451 arns fsx3008_arncs 0 397413 13866 383700 arns fsx3008_arns2 28834 58472 63862 0 arns fsx3008_ceres_ar0 0 11028350 105679 10929149 arns fsx3008_ceres_ar1 0 6248810 151129 6108160 arns fsx3008_ceres_ar2 0 5350713 90462 5262179 arns fsx3008_ceres_ar3 0 4027086 61709 3974189 arns fsx3008_ceres_ar4 0 1244903 45666 1200614 arns fsx3008_ceres_ar5 0 1129566 52327 1077901
期望输出(示例)
Project_Name Volume_Name InactiveTier PhysicalBlocks SSDtier GRIDtier Cold-Data PercentageRatio PercentageRatioAvg cayman fsx3008_cayman 80289 85639 85702 0 80289 93.75% 45.12%
当前错误输出
Project_Name Volume_Name InactiveTier PhysicalBlocks SSDtier GRIDtier Cold-Data PercentageRatio cayman fsx3008_cayman 80289 85639 85702 0 80289 0 cayman fsx3008_cayman 80289 85639 85702 0 0 ...(剩余内容略)
解决方案
可以通过awk分两次处理数据:第一次计算每行的Cold-Data和PercentageRatio,同时统计每个Project_Name的占比总和与行数;第二次输出时补充分组平均占比。
修改后的脚本如下:
#!/bin/bash awk ' BEGIN { # 格式化打印表头,保证列对齐 printf "%-15s %-20s %-15s %-18s %-10s %-10s %-12s %-20s %-20s\n", "Project_Name", "Volume_Name", "InactiveTier", "PhysicalBlocks", "SSDtier", "GRIDtier", "Cold-Data", "PercentageRatio", "PercentageRatioAvg" } FNR == 1 { next } # 跳过原始数据的表头行 { cold_data = $3 + $NF # 计算占比,避免除数为0的情况 if ($4 != 0) { ratio = (cold_data / $4) * 100 } else { ratio = 0 } # 保存当前行的格式化内容 lines[FNR] = sprintf("%-15s %-20s %-15d %-18d %-10d %-10d %-12d %-20.2f%%", $1, $2, $3, $4, $5, $6, cold_data, ratio) # 统计每个项目的占比总和与行数 sum_ratio[$1] += ratio count[$1] += 1 } END { # 遍历所有保存的行,补充平均占比后输出 for (i in lines) { # 提取当前行的项目名 split(lines[i], arr, / +/) proj = arr[1] avg_ratio = sum_ratio[proj] / count[proj] printf "%s %-20.2f%%\n", lines[i], avg_ratio } } ' ttk
脚本说明
- 表头处理:在
BEGIN块中用格式化输出对齐表头,提升可读性; - 跳过原始表头:
FNR == 1 { next }直接跳过输入文件的第一行表头; - 核心计算:计算
Cold-Data和占比,处理除数为0的异常情况; - 分组统计:用数组记录每个项目的占比总和与行数,为后续计算平均做准备;
- 最终输出:遍历保存的行数据,提取项目名后计算平均占比,补充到每行末尾输出。
这个脚本会解决重复行问题,正确计算占比并添加%符号,同时按Project_Name输出分组平均占比。
内容的提问来源于stack exchange,提问作者user2023
相关产品推荐
相关产品推荐

