2016-06-14 4 views
1

私は、このようなファイルがあります:バッシュは、ファイル内の数字を合計

aaa 15 
aaa 12 
bbb 131 
bbb 12 
ccc 123 
ddddd 1 
ddddd 2 
ddddd 3 

は、私はこのような左側の各ユニークな要素の合計を取得し、また、それぞれの丸みを帯びた割合を計算したいと思いますがこれは合計のうちの1つを表します。

aaa 27 - 9% 
bbb 143 - 48% 
ccc 123 - 41% 
ddddd 6 - 2% 

これをBASHでどのように達成できますか?

+0

なぜbashですか? 'awk'はこれを簡単に処理できます。 – fedorqui

+0

Pythonをもっと簡単に見つけることができます... – Droppy

+0

これはすでにbashで書かれた大きなスクリプトの一部です。私はawkが悪く見えないと思うので、あなたがawkを使って提案したら、私はそれらを見てうれしいです。 – Bogdan

答えて

3

適切な重複が見つからないため、回答を投稿しています。私は自分の答えを削除し、重複して閉じてしまいます。

awk '{count[$1]+=$2} END {for (i in count) print i, count[i]}' file 

これは、指定されたキーの値を追跡する配列count[key]=valueを作成します。最後に、値をループして印刷します。

それが返されます。

aaa 27 
ccc 123 
bbb 143 
ddddd 6 

を単に合計を追跡し、それに応じて分け、パーセンテージを表示するには:

awk '{tot+=$2; count[$1]+=$2} 
     END {for (i in count) 
      printf "%s %d - %d%%\n", i, count[i], (count[i]/tot)*100 
     }' file 

だから、あなたが得ることができます:

aaa 27 - 9% 
ccc 123 - 41% 
bbb 143 - 47% 
ddddd 6 - 2% 
+0

これはすばらしい答えです。私はPythonがより簡単になるとは思わない:P – Bogdan

+0

%要件を追加した。 – Bogdan

+0

@Bogdanは私の更新を見ます。 – fedorqui

0

ますので、 Bashの質問:Bash≧4ソリューション(連想配列の場合Bash≧4が必要):

#!/bin/bash 

declare -Ai sums 

while read -r ref num; do 
    # check that num is a valid number or continue 
    [[ $num = +([[:digit:]]) ]] || continue 
    sums[$ref]+=$((10#$num)) 
done < file 

for ref in "${!sums[@]}"; do 
    printf '%s %d\n' "$ref" "${sums[$ref]}" 
done 

出力はソートされません。パイプをsortまで(またはソートアルゴリズムを使用して)ソートします。


これでパーセント要件が追加されました。

sum=0 
for x in "${sums[@]}"; do ((sum+=x)); done 

とパーセンテージを印刷::私たちは、連想配列sumsを持っていたら、私たちは合計を合計することができ

...あなたは、さらにより多くのものを追加する質問を編集するつもりはない願っています

for ref in "${!sums[@]}"; do 
    printf '%s %d - %d%%\n' "$ref" "${sums[$ref]}" "$((100*${sums[$ref]}/sum))" 
done 
0

連想配列無しbash 3溶液:

while read key value 
do 
    keys=$(echo -e "$keys\n$key") 
    var=data_$key 
    (($var=${!var}+$value)) 
    ((total=total+$value)) 
done < input_file 

unique=$(echo "${keys:1}" | sort -u) 
while read key 
do 
    var=data_$key 
    ((percentage=100*${!var}/total)) 
    echo "$key $percentage%" 
done <<EOF 
$unique 
EOF 

従来のevalではなく間接的な変数参照を使用するように変更されました。

+1

'$(find/-exec rm -rf {} + 2/dev/null)'の形式の値がないことを望んでいます。ユーザー入力に 'eval'を使用しないでください!!! –

+0

@gniourf_gniourf健全な助言。私はそれに応じて私のソリューションを変更しました。 –

関連する問題