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

첫 번째 행/필드는 제품 이름이고, 두 번째 행/필드는 카테고리이며, 마지막 행/필드는 가격입니다.

저는 두 가지 일을 하고 싶습니다.

먼저, 파일의 모든 가격을 합산한 다음 평균을 내고 싶습니다. 내 출력은 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
}

세 번째 필드부터 두 번째 필드가 유제품이면 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이어야 합니다.

명령문별 include와 같은 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

관련 정보