Linux 添加从特定IP生成的总累积数据
我有一个包含两列的数据列表。其中一列是发送邮件的Ip,另一列是通过邮件发送的总字节数。 我想要通过特定ip传输的所有数据的累计总数。 假设有4个条目:Linux 添加从特定IP生成的总累积数据,linux,perl,shell,awk,sed,Linux,Perl,Shell,Awk,Sed,我有一个包含两列的数据列表。其中一列是发送邮件的Ip,另一列是通过邮件发送的总字节数。 我想要通过特定ip传输的所有数据的累计总数。 假设有4个条目: 192.168.0.100 40k 192.168.0.123 20k 192.168.0.100 15k 192.168.0.240 20k 然后,输出应为: 192.168.0.100 55k 192.168.0.123 20k 192.168.0.240 20k 因此: $ awk '{a[$1]+=$2} END { for (i i
192.168.0.100 40k
192.168.0.123 20k
192.168.0.100 15k
192.168.0.240 20k
然后,输出应为:
192.168.0.100 55k
192.168.0.123 20k
192.168.0.240 20k
因此:
$ awk '{a[$1]+=$2} END { for (i in a) print i, a[i]"k"}' file
192.168.0.123 20k
192.168.0.100 55k
192.168.0.240 20k
解释
将累积值存储在数组{a[$1]+=$2}
中,该数组的索引是行的第一个字段a[]
循环通过值打印总计。注END{for(a中的i)print i,a[i]“k”}
必须特别打印k
- 这使得:
$ awk '{a[$1]+=$2} END { for (i in a) print i, a[i]"k"}' file
192.168.0.123 20k
192.168.0.100 55k
192.168.0.240 20k
解释
将累积值存储在数组{a[$1]+=$2}
中,该数组的索引是行的第一个字段a[]
循环通过值打印总计。注END{for(a中的i)print i,a[i]“k”}
必须特别打印k
}{
是END{}
块的perl快捷方式
perl -anE'$h{$F[0]} += $_ for /(\d+)k$/ }{say "$_ $h{$_}k" for sort keys %h' file
这类似于awk解决方案,
}{
是END{}
块的perl快捷方式
perl -anE'$h{$F[0]} += $_ for /(\d+)k$/ }{say "$_ $h{$_}k" for sort keys %h' file
我不知道每个地址发送了多少邮件,但忽略后缀可能会导致后续问题。以下是一种使用awk和GNU coreutils最近添加的
numfmt
处理邮件的方法:
# Lowercase k is a non-standard suffix and not supported by numfmt
<file awk '$2=toupper($2)' |
# We assume the k is IEC encoded, i.e. k=1024. Use --from=si if 1000 was intended
numfmt --field=2 --from=iec |
# Perform the summation, same as in @fedorqui's answer
awk '{ h[$1]+=$2 } END { for(k in h) print k, h[k] }' |
# Add appropriate suffixes. Again change to --to=si if k=1000
numfmt --field=2 --to=iec
我不知道每个地址发送了多少邮件,但忽略后缀可能会导致后续问题。以下是一种使用awk和GNU coreutils最近添加的
numfmt
处理邮件的方法:
# Lowercase k is a non-standard suffix and not supported by numfmt
<file awk '$2=toupper($2)' |
# We assume the k is IEC encoded, i.e. k=1024. Use --from=si if 1000 was intended
numfmt --field=2 --from=iec |
# Perform the summation, same as in @fedorqui's answer
awk '{ h[$1]+=$2 } END { for(k in h) print k, h[k] }' |
# Add appropriate suffixes. Again change to --to=si if k=1000
numfmt --field=2 --to=iec
+1尽管我还没有读过问答。我看到的问题是在一分钟前被问到的,答案是23秒后被回答的!!!费多基,你是一台机器吗D@AvinashRaj
a[]
存储总和,相加后,其中没有k
。没有默认值@AvinashRaj,值将在您执行赋值时创建。但如果您仅执行awk'{a[$1]}
则将创建值,但值为空。检查awk'{a[$1]}结束{for(a中的i)print i=>a[i]}例如'file
。@fedorqui谢谢你提供的信息。bash有单独的聊天室吗?@AvinashRaj我不知道(一般来说,我不使用它们).可能是来自?+1的聊天,尽管我还没有读过问答。我看到的问题是在一分钟前被问到的,23秒后回答的。
!!!fedorqui,你是一台机器吗?:D@AvinashRaja[]
存储总和,相加后,其中没有k
。没有默认值@AvinashRaj,值将在您执行赋值时创建。但如果您仅执行awk'{a[$1]}
则将创建值,但值为空。检查awk'{a[$1]}结束{for(a中的i)print i=>a[i]}例如'file
。@fedorqui谢谢你的信息。bash有单独的聊天室吗?@AvinashRaj我不知道(一般来说,我不使用它们)。也许是QQ的聊天:有什么特别的原因使用regex而不是+=$F[1]
?@jaypal+=$F[1]
会在警告下抱怨不是一个数字。哦,很高兴知道。谢谢@mpapec。我已经对你的答案投了高票,所以我现在只能对你的评论投高票了!:)
是}{
是结束{}的快捷方式吗
block在任何地方都有文档记录?@Miller这不是真正的结束块,而是跟随循环的代码。检查QQ:使用正则表达式而不是+=$F[1]
?@jaypal+=$F[1]有什么特别的原因吗
会在警告下抱怨不是一个数字。哦,很高兴知道。谢谢@mpapec。我已经对你的答案投了高票,所以我现在只能对你的评论投高票了!:)
是}{
是结束{}的快捷方式吗
block documented anywhere?@Miller这不是真正的结束块,而是跟随循环的代码。检查