CSV数据处理需求咨询:每行加$5、按ID行求和及awk代码优化
CSV数据处理实现方案
需求说明
- 为每个ID对应的每一行数值列统一增加5美元
- 为每个ID计算对应行所有数值列的总和
原始数据示例
id;code;type;2023-06-30;2023-07-01;2023-07-02;2023-07-03;2023-07-04;2023-07-05;2023-07-06;2023-07-07;2023-07-08;2023-07-09;2023-07-10;2023-07-11;2023-07-12;2023-07-13;2023-07-14;2023-07-15;2023-07-16;2023-07-17;2023-07-18;2023-07-19;2023-07-20;2023-07-21;2023-07-22;2023-07-23;2023-07-24;2023-07-25;2023-07-26 018-118;speed violation;highway 27 OP RZ 27A-032 Rome "Rome",km 16 + 072;32;24225;31;25164;43;27562;40;24877;34;20993;47;26631;48;25119;3;1847;317;1;9465;2;7035;2;7556;5;7681;2;8401;(32+24225+31+25164+43+27562+40+24877+34+20993+47+26631+48+25119+3+1847+317+1+9465+2+7035+2+7556+5+7681+2+8401) 018-118;driveways;highway 27 OP RZ 27A-032 Rome, km 16 + 072;3;8416;9;9114;4;9482;4;9312;5;8459;1;8552;2;8563;5;8772;6;9006;4;11910;4;9276;5;8685;2;8261;2;(3+8416+9+9114+4+9482+4+9312+5+8459+1+8552+2+8563+5+8772+6+9006+4+11910+4+9276+5+8685+2+8261+2)
原始awk代码
awk ' BEGIN { FS = SUBSEP = ";" ORS = "" PROCINFO["sorted_in"] = "@ind_str_asc" } { date[$1] tuple[$3,$4,$6] val[$3,$4,$6,$1] = $5 } END { print "id;code;type" for (i in date) print FS i print "\n" for (i in tuple) { print i for (j in date) { k = i SUBSEP j print FS ( k in val ? val[k] : "" ) } print "\n" } } ' test/all.csv >test.csv
方案一:直接处理原始行数据
如果你的需求是基于原始CSV的每行数据进行处理,使用以下awk代码:
BEGIN { FS = ";" OFS = ";" } # 处理表头,添加总和列标题 NR == 1 { print $0, "total_amount" next } # 处理数据行:数值列加5并计算总和 { total = 0 # 遍历所有数值列(第4列到倒数第2列,跳过最后一列的手动总和公式) for (i = 4; i <= NF - 1; i++) { $i += 5 # 需求1:数值加5 total += $i # 需求2:累加计算总和 } # 输出修改后的行+计算出的总和 print $0, total }
说明
- 表头行追加
total_amount作为总和列的标题 - 数据行从第4列开始(前3列为非数值字段),每个数值加5,同时累加得到该行的总和
- 最后输出修改后的整行数据,末尾加上计算出的总和
方案二:基于原透视表逻辑调整
如果需要在你原代码生成的透视表基础上实现需求,调整后的代码如下:
BEGIN { FS = SUBSEP = ";" ORS = "" PROCINFO["sorted_in"] = "@ind_str_asc" } { date[$1] tuple[$3,$4,$6] # 需求1:给每个数值加5后存入数组 modified_val = $5 + 5 val[$3,$4,$6,$1] = modified_val # 需求2:累加每个ID组合的总和 sum[$3,$4,$6] += modified_val } END { print "id;code;type" for (i in date) print FS i # 添加总和列标题 print FS "total_amount\n" for (i in tuple) { print i for (j in date) { k = i SUBSEP j print FS ( k in val ? val[k] : "" ) } # 输出该ID组合的总和 print FS sum[i] "\n" } }
说明
- 读取数据时直接对数值加5,存入
val数组 - 维护
sum数组,累加每个(id,code,type)组合的所有数值总和 - 表头部分追加
total_amount列 - 每个组合行的末尾输出对应的总和值
内容的提问来源于stack exchange,提问作者Кирилл Ермолаев
相关产品推荐
相关产品推荐

