【发布时间】:2012-12-30 14:31:01
【问题描述】:
我有一个带有数值的排序文件
foo 2.3
bar 2.6
baz 4.7
并且希望有一个单行,将一行的百分位数放入最后一列,例如
foo 2.3 0.3333
bar 2.6 0.6666
baz 4.7 1.0000
谢谢。
【问题讨论】:
标签: 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
谢谢。
【问题讨论】:
标签: unix awk statistics percentile
我假设你的意思是行的百分比,为此你需要先知道行数。
这是使用 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
【讨论】:
percent of lines 会输出到第一列而没有分隔空格。
tot=NR-FNR 替换 FNR == NR { tot=NR; next } 或类似内容,只要您想在第二遍处理文件并计算行数在文件中。
虽然@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
【讨论】:
$ 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
【讨论】: