2

I have this input:

Fred apples 20
Susy oranges 5
Mark watermellons 12
Robert pears 4
Robert oranges 17
Terry oranges 9

Lisa peaches 7
Susy oranges 12
Mark grapes 39
Anne mangoes 7
Greg pineapples 3
Oliver rockmellons 2
Betty limes 14

and I want output like this:

Anne:
         mangoes  7
Oliver:
     rockmellons  2
Greg:
      pineapples  3
Mark:
    watermellons 12
          grapes 39
Terry:
         oranges  9
Susy:
         oranges 17
Lisa:
         peaches  7
Fred:
          apples 20
Robert:
         oranges 17
           pears  4
Betty:
           limes 14

I am trying to do it with awk command. My code looks like this:

{
lines[$1] = (lines[$1] ? lines[$1] "\n  "   $2 " "  $3 :  $1 ":\n       " $2 " " $3)


    }
    END {
        for (line in lines) print lines[line]
        }

I to compare duplicates in second collumn and sum the numbers.

  • The only problem is with Susy. Because my code will output this Susy: oranges 5 oranges 12 – Mafi May 17 '16 at 19:18
  • If you could use 2-dimensional arrays, indexed by name and fruit name, how would you solve it? – Mark Plotnick May 17 '16 at 19:28
  • { lines[$1,$2] = (lines[$1,$2] ? lines[$1,$2] "\n " $2 " " $3 : $1 ":\n " $2 " " $3) } END { for (line in lines) print lines[line,line] } – Mafi May 17 '16 at 19:44
  • Would this work? – Mafi May 17 '16 at 19:45
  • Think of a way to sum up the number of each type of fruit that each person has. You can use the + or += operator. – Mark Plotnick May 17 '16 at 19:47
3

Using GNU awk, which has arrays of arrays (may require gawk version 4)

gawk '
    NF  { n[$1][$2] += $3 }
    END {
        for (name in n) {
            print name ":"
            for (fruit in n[name]) 
                printf "%16s %2d\n", fruit, n[name][fruit]
        }
    }
'
| improve this answer | |
1

If you don't mind having the output sorted, you can keep track of the current person and the current fruit, and sum until either changes:

#!/usr/bin/awk -f

NF {
    if (who != $1) {
        if (count > 0) {
            printf "%16s %2d\n", fruit, count
        }
        who = $1
        printf "%s:\n", who
        fruit = ""
        count = 0
    }
    if (fruit != $2) {
        if (count > 0) {
            printf "%16s %2d\n", fruit, count
        }
        fruit = $2
        count = $3
    } else {
        count += $3
    }
}

END {
    printf "%16s %2d\n", fruit, count
}

Feed this with sort -k1,1 -k2,2:

sort -k1,1 -k2,2 file.txt | ./script.awk
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.