如何添加百分比列
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何添加百分比列相关的知识,希望对你有一定的参考价值。
我想计算所有行中每行的值百分比,并将其添加为另一列。输入(分隔符是 t):
1 10
2 10
3 20
4 40
添加第三列的所需输出显示基于第二列中的值计算的百分比:
1 10 12.50
2 10 12.50
3 20 25.00
4 40 50.00
我试图自己做,但是当我计算所有线的总数时,我不知道如何保持线的其余部分不变。非常感谢您的帮助!
答案
你去,一个 通过 步awk解决方案 -
awk 'NR==FNR{a = a + $2;next} {c = ($2/a)*100;print $1,$2,c }' file file
[jaypal:~/Temp] cat file
1 10
2 10
3 20
4 40
[jaypal:~/Temp] awk 'NR==FNR{a = a + $2;next} {c = ($2/a)*100;print $1,$2,c }' file file
1 10 12.5
2 10 12.5
3 20 25
4 40 50
更新:如果输出中的tab是必需的,则只需将OFS变量设置为“ t”。
[jaypal:~/Temp] awk -v OFS=" " 'NR==FNR{a = a + $2;next} {c = ($2/a)*100;print $1,$2,c }' file file
1 10 12.5
2 10 12.5
3 20 25
4 40 50
突破模式{action}语句:
- 第一种模式是
NR==FNR
。 FNR是awk的内置变量,用于跟踪给定文件中的记录数(默认情况下由新行分隔)。因此,在我们的案例中,FNR将是4.NR与FNR类似,但它不会重置为0.它继续增长。因此,在我们的案例中,NR将是8。 - 这种模式仅适用于前4个记录,这正是我们想要的。仔细阅读4条记录后,我们将总数分配给变量
a
。请注意,我们没有初始化它。在awk
,我们没有必要。但是,如果整个第2列为0,这将会中断。因此,您可以通过在第二个操作语句中添加if语句来处理它,即仅当> 0表示除以0或其他时才进行除法。 next
是必需的,因为我们并不真的想要执行第二个模式{action}语句。next
告诉awk停止进一步行动并转移到下一个记录。- 一旦解析了四个记录,下一个模式{action}就会开始,这非常简单。执行百分比并打印第1列和第2列以及它们旁边的百分比。
注意:正如注释中提到的@lhf一样,只要您在文件中包含数据集,此单行内容就会起作用。如果通过管道传递数据,它将无法工作。
在评论中,有一个讨论如何使这个awk one-liner
从pipe
而不是file
输入。好吧,我能想到的唯一方法是将列值存储在array
中,然后使用for loop
将每个值与它们的百分比一起吐出。
现在arrays
中的awk
是associative
并且永远不会按顺序排列,即从数组中拉出值将不会与它们进入的顺序相同。所以如果可以,那么下面的单行应该可以工作。
[jaypal:~/Temp] cat file
1 10
2 10
3 20
4 40
[jaypal:~/Temp] cat file | awk '{b[$1]=$2;sum=sum+$2} END{for (i in b) print i,b[i],(b[i]/sum)*100}'
2 10 12.5
3 20 25
4 40 50
1 10 12.5
为了使它们按顺序排列,您可以将结果传递给sort
。
[jaypal:~/Temp] cat file | awk '{b[$1]=$2;sum=sum+$2} END{for (i in b) print i,b[i],(b[i]/sum)*100}' | sort -n
1 10 12.5
2 10 12.5
3 20 25
4 40 50
另一答案
你可以在几个通行证中完成
#!/bin/bash
total=$(awk '{total=total+$2}END{print total}' file)
awk -v total=$total '{ printf ("%s %s %.2f
", $1, $2, ($2/total)*100)}' file
另一答案
你需要逃脱它作为%%
。例如:
printf("%s %s %s%%
", $1, $2, $3)
另一答案
也许有更好的方法,但我会传递文件两次。
'infile'的内容:
1 10
2 10
3 20
4 40
'script.awk'的内容:
BEGIN {
## Tab as field separator.
FS = " ";
}
## First pass of input file. Get total from second field.
ARGIND == 1 {
total += $2;
next;
}
## Second pass of input file. Print each original line and percentage as third field.
{
printf( "%s %2.2f
", $0, $2 * 100 / total );
}
在我的linux框中运行脚本:
gawk -f script.awk infile infile
结果:
1 10 12.50
2 10 12.50
3 20 25.00
4 40 50.00
以上是关于如何添加百分比列的主要内容,如果未能解决你的问题,请参考以下文章