1

I have a csv file with this:

country,gender,sport,height,weight,gold,silver
ESP,male,football,1.8,84,0,1
VEN,female,handball,1.6,59,1,0
ESP,male,athletics,1.7,65,0,0

I need to write a script using awk that prints the max, min, avg of height and weight and the sum of the column gold and silver for group by each country and gender indicated in the parameters

When running:

gawk -f script3_4.awk -v sport=football sex=male athletes.csv

the output should be something like this:

country,gender,maxH,minH,avgH,maxW,minW,avgW,sum_medals
ESP,male,1.98,1.73,1.86,70,120,85,7
BRA,male,1.94,1.65,1.7,65,112,91,9
...

I know how to calculate min max and average, however I am very new using awk and I don't know how to group the data by gender and country.

Can someone help me?

2
  • That command line is messy and inconsistent within itself and using variables less than ideally, are you sure you want to create a script based on that? Why is that the command line you want to use instead of a simpler, more idiomatic one?
    – Ed Morton
    Dec 11, 2022 at 12:07
  • 1
    Regarding the output should be something like this: - no, provide the exact expected output given the sample input you provided so we have something to test a potential solution against. Since you know how to calculate min max and average, edit your question to show how you do that so we can help you with your code.
    – Ed Morton
    Dec 11, 2022 at 12:10

1 Answer 1

0

This looks like homework so I'm not going to give a complete answer, just a hint and a partial example:

For each country, you'll need to keep track of the max and min height & weight, the cumulative total height and weight, cumulative total of medals, and a count of the number of records (so you can calculate the average later).

To do that, use several associative arrays (one for each tracked value), using $1 (country) as the array key.

For example:

if ($2 == gender && $3 == sport) {
  count[$1]++;
  medals[$1] += $6 + $7;

  if ($4 > maxH[$1]) {maxH[$1] = $4};
  if ($4 < minH[$1]) {minH[$1] = $4};
  totalH[$1] += $4;

  if ($5 > maxW[$1]) {maxW[$1] = $5};
  if ($5 < minW[$1]) {minW[$1] = $5};
  totalW[$1] += $5;
}

I'll leave the output stage and calculation of averages to you.


If you actually need to keep track of the distinct values for country and gender simultaneously, you can use some kind of multi-dimensional array.

gawk supports arrays of arrays so this would be a little easier than with a traditional awk (see Multidimensional Arrays and Arrays of Arrays)

e.g. using country ($1) and gender ($2) as the keys for the array dimensions.

if ($3 == sport) {
  count[$1][$2]++;
  medals[$1][$2] += $6 + $7;

  if ($4 > maxH[$1][$2]) {maxH[$1][$2] = $4};
  if ($4 < minH[$1][$2]) {minH[$1][$2] = $4};
  totalH[$1][$2] += $4;

  if ($5 > maxW[$1][$2]) {maxW[$1][$2] = $5};
  if ($5 < minW[$1][$2]) {minW[$1][$2] = $5};
  totalW[$1][$2] += $5;
}

Finally, if you needed to group by sport as well as country and gender, you could use a third array dimension with sport ($3) as the key.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .