![如何使用 awk 命令聚合以下记录](https://linux22.com/image/148847/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20awk%20%E5%91%BD%E4%BB%A4%E8%81%9A%E5%90%88%E4%BB%A5%E4%B8%8B%E8%AE%B0%E5%BD%95.png)
我有以下记录作为输入:abc.dat
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~12~0~1
现在我需要根据第 1 到第 10 字段分组来聚合第 11、12 和 13 字段。
这样我的输出应该是这样的:
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~192~0~16
尝试了以下方法:
awk 'BEGIN{FS=OFS="~";}{a[$1,$2,$3,$4,$5,$6,$7,$8,$9,$10]+=$11;b[$1,$2,$3,$4,$5,$6,$7,$8,$9,$10]+=$12;c[$1,$2,$3,$4,$5,$6,$7,$8,$9,$10]+=$13} END {for (i in a) print i,a[i],b[i],c[i]}' abc.dat > abc1.dat
但输出如下:
201901^Y230615^Y41302^Yblank^Yblank^Y05^YU099164^YARS^Yblank^Y030~192~0~16
一个额外的^Y
符号即将到来。
答案1
真奇怪。当在数组键中使用时,它看起来像是awk
被窒息了。~
可能是因为~
是 匹配运算符,但我不确定。无论如何,这都会如您所愿:
$ awk 'BEGIN{FS=OFS="~";}
{
key=$1"~"$2"~"$3"~"$4"~"$5"~"$6"~"$7"~"$8"~"$9"~"$10;
a[key]+=$11;
b[key]+=$12;
c[key]+=$13
}
END {
for (i in a){
print i,a[i],b[i],c[i]
}
}' file
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~192~0~16
答案2
如果您对非awk
解决方案没意见,您可以csvsql
尝试csvkit,这将是一个完美的工具:
csvsql -H -d '~' --query '
select a,b,c,d,e,f,g,h,i,j,sum(k),sum(l),sum(m)
from file
group by a,b,c,d,e,f,g,h,i,j
' file
输出:
201901,230615,41302,blank,blank,5,U099164,ARS,blank,30,192,0,16
如果您需要输出以~
- 分隔,请添加| csvformat -D '~'
.
答案3
我通过使用 awk 和 sed 的组合通过以下方法完成
awk -F "~" 'BEGIN{sum=0;add=0;wo=0}{sum=sum+$NF}{add=add+$(NF-2)}{wo=wo+$(NF-1)}END{$NF=" ";$(NF-1)=" ";$(NF-2)=" ";print $0,add,wo,sum}' filename | sed -r "s/\s+/ /g"| sed "s/ /~/g"
输出
awk -F "~" 'BEGIN{sum=0;add=0;wo=0}{sum=sum+$NF}{add=add+$(NF-2)}{wo=wo+$(NF-1)}END{$NF=" ";$(NF-1)=" ";$(NF-2)=" ";print $0,add,wo,sum}' p.txt | sed -r "s/\s+/ /g"| sed "s/ /~/g"
201901~230615~41302~blank~blank~05~U099164~ARS~blank~030~192~0~16
答案4
当您执行此操作时:a[$1,$2,$3,$4,$5,$6,$7,$8,$9,$10]+=$11
awk 使用此作为键:$1 SUBSEP $2 SUBSEP $3 SUBSEP $4 SUBSEP $5 SUBSEP $6 SUBSEP $7 SUBSEP $8 SUBSEP $9 SUBSEP $10
其中各个元素由变量的内容连接SUBSEP
。默认情况下该值为“\034”。
看https://www.gnu.org/software/gawk/manual/html_node/MultiDimension.html
为了适应这一点,请使用BEGIN{FS = OFS = SUBSEP = "~"}