使用awk获取文件中行的百分位数

时间:2013-01-16 09:55:08

标签: unix awk statistics percentile

我有一个带有数值的排序文件,如

foo 2.3
bar 2.6
baz 4.7

并希望有一个单行,将一行的百分位数放入最后一列,例如

foo 2.3 0.3333
bar 2.6 0.6666
baz 4.7 1.0000

谢谢。

3 个答案:

答案 0 :(得分:2)

我假设你的意思是线的百分比,为此你需要首先知道线的数量。

这是使用awk作为双程解决方案的一种方法:

 awk 'FNR == NR { tot=NR; next } { printf( "%s %.4f\n", $0, FNR/tot) }' file file 

输出:

foo 2.3 0.3333
bar 2.6 0.6667
baz 4.7 1.0000

第一个阻止仅在FNR == NR期间有效,即第一次通过。第二个块负责打印。

确定文件长度的其他替代方法

开始第二遍(NR-1)时使用FNR != NR

awk 'FNR != NR { if(!tot) tot=NR-1; printf( "%s %.4f\n", $0, FNR/tot) }' file file

在运行awk之前使用wc

awk -v tot=$(wc -l < file) '{ printf( "%s %.4f\n", $0, FNR/tot) }' file

答案 1 :(得分:2)

$ awk 'c=NR-FNR{printf "%s %.4f\n",$0,FNR/c}' file file
foo 2.3 0.3333
bar 2.6 0.6667
baz 4.7 1.0000

答案 2 :(得分:1)

即使@thor解决方案很好,也没有必要遍历文件两次。相反,我们可以在内存本身内完成。

awk '{a[NR]=$0;}END{for(i=1;i<=NR;i++)print a[i],i/NR;}' your_file

测试:

> cat temp
foo 2.3
bar 2.6
baz 4.7
> awk '{a[NR]=$0;}END{for(i=1;i<=NR;i++)print a[i],i/NR;}' temp
foo 2.3 0.333333
bar 2.6 0.666667
baz 4.7 1

如果您具体说明精度,请使用以下内容:

> awk '{a[NR]=$0;}END{for(i=1;i<=NR;i++)printf("%s %0.4f\n",a[i],i/NR);}' temp
foo 2.3 0.3333
bar 2.6 0.6667
baz 4.7 1.0000