如何计算linux中的百分比

时间:2017-04-20 09:52:40

标签: 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执行以下步骤:

  1. COL3 = col2的/ Col1中。
  2. 使用百分比
  3. 格式化Col3
  4. 使用countif按Col3分组
  5. 如何在linux命令行中使用awk或其他方式执行此任务?

    预期结果:

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

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

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

5 个答案:

答案 0 :(得分:2)

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

示例输出:

percent|count
0-20%|3
21-50%|1
51-100%|6

答案 1 :(得分:1)

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

awk -F ',' -v Step='0|20|50|100' '
   BEGIN {
      # define group
      Gn = split( Step, aEdge, "|")
      }
   NR>1{
   # Define wich percent
   L = $2 * 100 / ($1>0 ? $1 : 1)
   # in which group
   for( j=1; ( L < aEdge[j] || L >= aEdge[j+1] ) && j < Gn;) j++
   # add to group
   G[j]++
   }

   # print result ordered
   END {
      print "percent|count"
      for( i=1;i<Gn;i++) printf( "%d-%d%%|%d\n", aEdge[i], aEdge[i+1], G[i])
      }
   ' data

答案 2 :(得分:1)

另一个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

答案 3 :(得分:1)

另一个,在GNU awk中,使用switch和正则表达式来标识值(因为parsing在OP中被标记):

NR>1{
    switch(p=$2/$1){
    case /0\.[01][0-9]|\.20/:
        a["0-20%"]++;
        break;
    case /\.[2-4][0-9]|\.50/:
        a["21-50%"]++;
        break;
    default:
        a["51-100%"]++
    }
}
END{ for(i in a)print i, a[i] }

运行它:

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

答案 4 :(得分:1)

Pure 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 25 45 50 < csv.dat
percent|count
 0- 20%|    3
25- 45%|    1
50-100%|    6

说明:

  1. lower设置为一个表达式,用于计算小于100*val/num
  2. 的百分比数
  3. 间隔列表使用0和100进行扩充,以便正确打印限制
  4. 标题行被忽略
  5. 打印输出标题
  6. 对于每个csv行,请阅读变量$num$val,并将$lower(使用这些变量)的数字评估发送给...
  7. 计算每个间隔计数的实例数...
  8. 并打印间隔和计数