$ cat "

Linux Kata #2: Ordering Lunch

"

This is a kata with a couple of different difficulty levels.

Level 1:

Count how many attendees what chicken for lunch and how many want tofu. It's OK to run two separate commands to get the counts.

Here is the file contents of the file food.txt. It's worth noting that the file contains a mix of spaces and tabs as column separators.

Name                	Attendance        	Response    Food
Allen Key Meeting Organizer None Chicken
Bob Sled Required Attendee Accepted Tofu
Clay Pigeon Required Attendee Accepted Chicken
Cliff Edge Required Attendee Accepted Tofu
Guy Ropes Required Attendee Accepted Tofu
Jack Hammer Required Attendee Accepted Chicken
Jerry Cann Required Attendee Declined
Jim Boot Required Attendee Accepted Chicken
Jim Equipment Required Attendee Accepted Chicken
Jock Strap Required Attendee Accepted Tofu
Lou Paper Required Attendee Accepted Chicken
Mike Stand Required Attendee Declined
Morris Minor Required Attendee Accepted Chicken
Phillip Screwdriver Required Attendee Accepted Chicken
Ray Gunn Required Attendee Accepted Tofu
Roman Bath Required Attendee Accepted Tofu
Stanley Knife Required Attendee Accepted Chicken
Terry Towelling Required Attendee Accepted Tofu
Walter Closet Required Attendee Accepted Chicken
Catherine Wheel Required Attendee Declined Chicken
Joy Stick Required Attendee Accepted Tofu
Kitty Litter Required Attendee Accepted Tofu
Pearl Necklace Required Attendee Accepted Tofu
Penny Farthing Required Attendee Declined Chicken
Jim Nazium Required Attendee Declined

Level 2:

Same task as level 1, but the result from your command/script should be a single line with the format "Tofu: 10, Chicken: 12"


Level 3:

Same task as level 2, but the lunch options may consist of multiple words.

Here's the file contents of the file food2.txt. There's a mix of spaces and tabs in this file as well.

Name                	Attendance        	Response    Food
Allen Key Meeting Organizer None Chicken
Bob Sled Required Attendee Accepted Fried tofu
Clay Pigeon Required Attendee Accepted Chicken
Cliff Edge Required Attendee Accepted Fried tofu
Guy Ropes Required Attendee Accepted Fried tofu
Jack Hammer Required Attendee Accepted Chicken
Jerry Cann Required Attendee Declined
Jim Boot Required Attendee Accepted Chicken
Jim Equipment Required Attendee Accepted Chicken
Jock Strap Required Attendee Accepted Fried tofu
Lou Paper Required Attendee Accepted Chicken
Mike Stand Required Attendee Declined
Morris Minor Required Attendee Accepted Chicken
Phillip Screwdriver Required Attendee Accepted Chicken
Ray Gunn Required Attendee Accepted Fried tofu
Roman Bath Required Attendee Accepted Fried tofu
Stanley Knife Required Attendee Accepted Chicken
Terry Towelling Required Attendee Accepted Fried tofu
Walter Closet Required Attendee Accepted Chicken
Catherine Wheel Required Attendee Declined Chicken
Joy Stick Required Attendee Accepted Fried tofu
Kitty Litter Required Attendee Accepted Fried tofu
Pearl Necklace Required Attendee Accepted Fried tofu
Penny Farthing Required Attendee Declined Chicken
Jim Nazium Required Attendee Declined

The output should still be "Tofu: 10, Chicken: 12".


Suggested solution for level 1:

cat food.txt | grep Tofu | wc -l;cat food.txt | grep Chicken | wc -l

These commands basicly just lists the entire file contents, filters out all lines containing the word Tofu/Chicken and then counts the number of filtered lines.


Suggested solution for level 2:

awk '{if ($NF == "Tofu") tofu_count += 1; else if ($NF == "Chicken") chicken_count += 1 } END {print "Tofu: ",tofu_count,", Chicken: ",chicken_count}' food.txt

This AWK program matches has no filtering condition, so it matches all lines. For each line which has Tofu/Chicken as the last word it increments the corresponding variable. When all lines have been processed it outputs the values in the variables and some additional text. NF is a magical variable containing the number of fields in a record. $ is used to extract a field with a given 1-based index. So $NF evaluates to the last word on a given line.


Suggested solution for level 3:

awk 'BEGIN {FS = " {2,}|\t+"}{if ($NF == "Fried tofu") tofu_count += 1; else if ($NF == "Chicken") chicken_count += 1} END {print "Tofu: ",tofu_count,", Chicken: ",chicken_count}' food2.txt
Tofu: 10 , Chicken: 12

Most of the script is the same as in the solution for the level 2 problem. However, in this script the field separator has been customized so that words separated by a single space are considered to be part of the same field. The FS variable contains the field separator expression, which in this case is a regular expression which matches 2 or more spaces or 1 or more tabs.

Written by Erik Öjebo 2012-12-17 21:06

    Comments