【问题标题】:Using awk to get the percentile of lines in a file使用 awk 获取文件中行的百分位数
【发布时间】: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


    【解决方案1】:

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

    这是使用 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 会输出到第一列而没有分隔空格。
    • @MarioKonschake:它适用于 gawk 和 nawk,你使用的是哪个版本的 awk?
    • 对您的文件运行命令 dos2unix。看起来它包含 ^M 个字符
    • @sarathi 那么这是正确的方法,因为您无法在数组中存储那么多数据。
    • +1 表示该方法,但您可以在任何脚本中仅用 tot=NR-FNR 替换 FNR == NR { tot=NR; next } 或类似内容,只要您想在第二遍处理文件并计算行数在文件中。
    【解决方案2】:

    虽然@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
    

    【讨论】:

      【解决方案3】:
      $ 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
      

      【讨论】:

        猜你喜欢
        • 2017-08-31
        • 1970-01-01
        • 2015-02-14
        • 1970-01-01
        • 2015-10-21
        • 1970-01-01
        • 2015-08-16
        • 2011-01-25
        • 2019-04-13
        相关资源
        最近更新 更多