2017-04-20 161 views
0

樣品輸入數據:如何計算的百分比在linux

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. 格式COL3有個
  3. 使用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' 
+0

你嘗試過這麼遠嗎? –

+0

我計算了百分比,但我仍然找到了按Col3組合的方法'cat input.txt | awk -F「,」'$ 3 = 100 * $ 2/$ 1'' –

回答

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%或不但不是真正的目的)

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 
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 
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 
1

純bash下

# arguments are histogram boundaries *in ascending order* 
hist() { 
    local lower=0$(printf '+(val*100>sum*%d)' "[email protected]") val sum count n; 
    set -- 0 "[email protected]" 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. 區間列表增加了0和100,以便限制正確
  3. 打印標題行被忽略
  4. 輸出頁眉打印
  5. 對於每個CSV行,讀取變量$num$val和發送的$lower數字評價(使用那些變量)...
  6. 計算每個間隔計數的實例數...
  7. 和打印的時間間隔和計數