awkを使用してレコード全体で同じ行にエントリを追加するには?

awkを使用してレコード全体で同じ行にエントリを追加するには?

awkにもう少し慣れるように努力しています。この.txtドキュメントを作成してfood.txtと名​​前を付けましたが、面倒なことに製品の価格をどのように合計するのかわかりません。次のtxtファイルを例にしてみましょう。

Milk dairy 3.89
Cheese dairy 2.12
Eggs produce 1.28
Yogurt dairy 1.49
Chicken produce 2.19
Muffin pastries 0.49
Cookie pastries 0.99

最初の行/フィールドは製品名、2番目の行/フィールドはカテゴリ、最後の行/フィールドは価格です。

私は2つのことをしたいと思います。

まず、ファイルのすべての価格を合計してから平均を出したいと思います。私の出力は1.78(丸め)でなければなりません。

第二に、すべての乳製品の価格を追加して乳製品の平均価格を取得したいと思います。この場合、私の出力は2.50でなければなりません。

私は最初にawkに触れたので、私のtxtドキュメントがうまくいくべきかどうかわかりません。ただ実験して自分でやってみました。

私が試したコードは次のとおりです。なぜ動作しないのか分かりません。

BEGIN{ avg = 0 }

{
   total = 0
     for(i = 3; i <= NF; i++)
       if ($2 == "dairy")
       total = total +$i
   avg += total
}

END{
        print "Total Dairy Price Average =  $" avg/NR
}

3番目のフィールドから2番目のフィールドが乳製品の場合、total = total + $ iに設定されていると思います。これは平均+ =合計です。しかし、このプログラムを実行すると1.07のような結果が出ますが、これはその近くにもありません。

答え1

Awk方法:

$ awk '{ cat=$(NF-1); a[cat] += $NF; sum += $NF; b[cat]++ }
       END{ for (cat in a) print cat, a[cat]/b[cat]; print "all avg", sum/NR }' file

出力:

dairy 2.5
produce 1.735
pastries 0.74
all avg 1.77857

答え2

まず、ファイルのすべての価格を合計してから平均を出したいと思います。私の出力は1.78(丸め)でなければなりません。

NRファイルを処理するときに現在の行番号を含めると、句に行の総数ENDが表示されます。たとえば、次のようになります。

awk '{ sum+=$3 } END { print sum, sum/NR }'

または丸められた数字を使用してください。

awk '{ sum+=$3 } END { print sum, sum/NR }' OFMT='%.2f'

第二に、すべての乳製品の価格を追加して乳製品の平均価格を取得したいと思います。この場合、私の出力は2.50でなければなりません。

ステートメント固有のインクルードなどのawkに付属の組み込み機能はほとんど使用されませんboolean_expression { actions }。したがって、次の行を実行してください$2 == "dairy"

awk '$2 == "dairy" { sum+=$3; count++ } END { print sum, sum/count }'

答え3

OPが説明を求めたので試してみましょう。答えはRomanPerekhrestの答えに基づいていますが、少し異なります。

#!/bin/awk -f

{ 
    products = $2 # Store the second field in products
    a[products] += $NF # Increment each item in the array. $NF denotes the last field. 
    total += $NF # This is the total count of the last field all together resulting in a total of:  12.45
    pr[products]++  #increment by 1 if item found in second field. For dairy this should be 3
} 
END { 
    for (products in a)  # for loop
      print products, a[products] / pr[products]  # print product name, total of products / products found
      printf("All avg: %.2f\n", total/NR); # Print average of all products. So 12.45 / 7 = 1.778571
}

呼び出しスクリプトは次のとおりです。

chmod u+x myawkscript.awk && ./myawkscript.awk inputfile 

答え4

製品全体の平均

total_number_of_produts=`awk 'END{print NR}' filename`

awk -v t0="$total_number_of_produts" 'BEGIN{sum=0}{sum=sum+$NF}END{print sum/t0}' filename

output
1.777 (1.78)

乳製品の平均

da=`awk '/dairy/{print NR}' filename | wc -l`

awk -v t0="$total_number_of_produts" 'BEGIN{sum=0}{sum=sum+$NF}END{print sum/t0}' filename 


output
2.5

関連情報