在linux中如何计算百分比

在linux中如何计算百分比,linux,parsing,awk,Linux,Parsing,Awk,示例输入数据: Col1, Col2 120000,1261 120000,119879 120000,117737 120000,14051 200000,58411 200000,115292 300000,279892 120000,98572 250000,249598 120000,14051 ...... 我使用Excel的步骤如下: Col3=Col2/Col1 使用百分比设置Col3的格式 使用countif按Col3分组 如何在linux命令行中使用awk或其他方式完成此

示例输入数据:

Col1, Col2
120000,1261
120000,119879
120000,117737
120000,14051
200000,58411
200000,115292
300000,279892
120000,98572
250000,249598
120000,14051
......  
我使用Excel的步骤如下:

  • Col3=Col2/Col1
  • 使用百分比设置Col3的格式
  • 使用countif按Col3分组
  • 如何在linux命令行中使用awk或其他方式完成此任务

    预期结果:

    percent|count
    0-20%  |  10
    21-50% |  5
    51-100%|  10
    

    我计算了百分比,但我仍在寻找按Col3分组的方法

    cat input.txt |awk -F"," '$3=100*$2/$1'
    

    awk进近:

    awk 'BEGIN {
        FS=",";
        OFS="|";
    }
    (NR > 1){
        percent = 100 * $2 / $1;
        if (percent <= 20) {
            a["0-20%"] += 1; 
        } else if (percent <= 50) {
            a2 += 1; 
            a["21-50%"] += 1; 
        } else {
            a["51-100%"] += 1; 
        }
    }
    END {
        print "percent", "count"
        for (i in a) {
            print i, a[i];
        }
    }' data
    

    awk进近:

    awk 'BEGIN {
        FS=",";
        OFS="|";
    }
    (NR > 1){
        percent = 100 * $2 / $1;
        if (percent <= 20) {
            a["0-20%"] += 1; 
        } else if (percent <= 50) {
            a2 += 1; 
            a["21-50%"] += 1; 
        } else {
            a["51-100%"] += 1; 
        }
    }
    END {
        print "percent", "count"
        for (i in a) {
            print i, a[i];
        }
    }' data
    

    一个通用的自我记录。需要根据结果中的组名进行一些微调(由于+1%或非+1%,但不是真正的目的)

    awk-F','-v步骤='0 | 20 | 50 | 100''
    开始{
    #定义组
    Gn=拆分(步骤,aEdge,“|”)
    }
    NR>1{
    #定义中间百分比
    L=$2*100/($1>0?$1:1)
    #哪一组
    对于(j=1;(L=aEdge[j+1])&&j对于(i=1;i一个通用的自我记录。需要根据结果中的组名进行一些微调(由于+1%或非+1%,但不是真正的目的)

    awk-F','-v步骤='0 | 20 | 50 | 100''
    开始{
    #定义组
    Gn=拆分(步骤,aEdge,“|”)
    }
    NR>1{
    #定义中间百分比
    L=$2*100/($1>0?$1:1)
    #哪一组
    对于(j=1;(L=aEdge[j+1])&&j对于(i=1;i另一个
    awk
    ,带有参数化存储箱和格式化输出

    $ awk -F, -v OFS=\| -v bins='20,50,100' '
         BEGIN {n=split(bins,b)} 
         NR>1  {for(i=1;i<=n;i++) 
                  if($2/$1 <= b[i]/100) 
                    {a[b[i]]++; next}} 
         END   {print "percent","count"; 
                b[0]=-1; 
                for(i=1;i<=n;i++) 
                  printf "%-7s|%3s\n", b[i-1]+1"-"b[i]"%",a[b[i]]}' file
    
    percent|count
    0-20%  |  3
    21-50% |  1
    51-100%|  6
    
    $awk-F,-v OFS=\\|-v bins='20,50100''
    开始{n=split(bin,b)}
    
    NR>1{for(i=1;i另一个
    awk
    ,带有参数化存储箱和格式化输出

    $ awk -F, -v OFS=\| -v bins='20,50,100' '
         BEGIN {n=split(bins,b)} 
         NR>1  {for(i=1;i<=n;i++) 
                  if($2/$1 <= b[i]/100) 
                    {a[b[i]]++; next}} 
         END   {print "percent","count"; 
                b[0]=-1; 
                for(i=1;i<=n;i++) 
                  printf "%-7s|%3s\n", b[i-1]+1"-"b[i]"%",a[b[i]]}' file
    
    percent|count
    0-20%  |  3
    21-50% |  1
    51-100%|  6
    
    $awk-F,-v OFS=\\|-v bins='20,50100''
    开始{n=split(bin,b)}
    
    NR>1{for(i=1;iother,在GNU awk中,使用
    switch
    和regex来识别值(因为
    parsing
    在OP中被标记):

    运行它:

    $ awk -F, -f program.awk file
    21-50% 1
    0-20% 3
    51-100% 6
    

    另一种是在GNU awk中,使用
    开关
    和regex来识别值(因为
    解析
    在OP中被标记):

    运行它:

    $ awk -F, -f program.awk file
    21-50% 1
    0-20% 3
    51-100% 6
    
    纯bash:

    # arguments are histogram boundaries *in ascending order*
    hist () {
      local lower=0$(printf '+(val*100>sum*%d)' "$@") val sum count n;
      set -- 0 "$@" 100;
      read -r
      printf '%7s|%5s\n' percent count;
      while IFS=, read -r sum val; do echo $((lower)); done |
      sort -n | uniq -c |
      while read count n; do
        printf '%2d-%3d%%|%5d\n' "${@:n+1:2}" $count;
      done
    }
    
    例如:

    $ hist 20 50 < csv.dat
    percent|count
     0- 20%|    3
    20- 50%|    1
    50-100%|    6
    
    $hist 20 50
    潜在问题:不打印没有值的间隔:

    $ hist 20 25 45 50 < csv.dat
    percent|count
     0- 20%|    3
    25- 45%|    1
    50-100%|    6
    
    $hist 20 25 45 50
    说明:

  • lower
    设置为一个表达式,该表达式将计算小于
    100*val/num
  • 间隔列表增加了0和100,以便正确打印限制
  • 标题行被忽略
  • 打印输出标题
  • 对于每个csv行,读取变量
    $num
    $val
    ,并将
    $lower
    (使用这些变量)的数值计算发送到
  • 计算每个间隔计数的实例数
  • 并打印间隔和计数
  • 纯bash:

    # arguments are histogram boundaries *in ascending order*
    hist () {
      local lower=0$(printf '+(val*100>sum*%d)' "$@") val sum count n;
      set -- 0 "$@" 100;
      read -r
      printf '%7s|%5s\n' percent count;
      while IFS=, read -r sum val; do echo $((lower)); done |
      sort -n | uniq -c |
      while read count n; do
        printf '%2d-%3d%%|%5d\n' "${@:n+1:2}" $count;
      done
    }
    
    例如:

    $ hist 20 50 < csv.dat
    percent|count
     0- 20%|    3
    20- 50%|    1
    50-100%|    6
    
    $hist 20 50
    潜在问题:不打印没有值的间隔:

    $ hist 20 25 45 50 < csv.dat
    percent|count
     0- 20%|    3
    25- 45%|    1
    50-100%|    6
    
    $hist 20 25 45 50
    说明:

  • lower
    设置为一个表达式,该表达式将计算小于
    100*val/num
  • 间隔列表增加了0和100,以便正确打印限制
  • 标题行被忽略
  • 打印输出标题
  • 对于每个csv行,读取变量
    $num
    $val
    ,并将
    $lower
    (使用这些变量)的数值计算发送到
  • 计算每个间隔计数的实例数
  • 并打印间隔和计数

  • 我计算了百分比,但我仍在寻找按Col3
    cat input.txt|awk-F“,“$3=100*$2/$1”分组的方法。
    我计算了百分比,但我仍在寻找按Col3
    cat input.txt|awk-F“,“$3=100*$2/$1”分组的方法。