I'm making birthday tracker for only a few people and was wondering how to combine all if statements into one since date and name are the only different things in every if statement, rest is same format.
date=`date %b-%d`
echo $date
if [ $date == "Sep-09" ]; then
echo "Happy Birthday abc!"
fi
if [ $date == "Oct-11" ]; then
echo "Happy Birthday xyz!"
fi
.
.
.
I think I can use positional arguments ($1 for date, $2 for name..) but can't figure out how to use it for multiple dates and names. Or if there's any better way, that would be good to know as well.
CodePudding user response:
Using case:
...
case "$date" in
"Sep-09") name=abc;;
"Oct-11") name=xyz;;
...
*) exit;; # if no condition met
esac
echo "Happy Birthday $name!"
CodePudding user response:
You can use map/dictionary data structure here. You can check example here: How to define hash tables in Bash?
CodePudding user response:
You could store your birthdays in a text file and read them with while
and read
.
read
will let you read into one or more variables, and if there's more words than variables it stuffs all remaining words into the last variable, so it's perfect to use here when the person's name could be multiple words:
help read
The line is split into fields as with word splitting, and the first word is assigned to the first NAME, the second word to the second NAME, and so on, with any leftover words assigned to the last NAME. Only the characters found in $IFS are recognized as word delimiters.
I also suggest using the date format %m-%d
rather than %b-%d
as it means the dates in your file will be in order (e.g. you can run sort birthdays.txt
to see everyone in birthday order, which you couldn't do if the month was represented by 3 letters).
birthdays.txt
:
09-08 John Smith
10-11 Alice
checkbirthdays.sh
:
#!/bin/bash
nowdate="$(date %m-%d)"
(
while read checkdate name ; do
if [ "$nowdate" = "$checkdate" ] ; then
echo "Happy Birthday $name!"
fi
done
) < birthdays.txt
output of ./checkbirthdays.sh
on September 8th:
Happy Birthday John Smith!
CodePudding user response:
Assuming you have bash
4.0 or newer and, names don't contain whitespace or glob characters, using an associative array would be appropriate for this task:
#!/bin/bash
declare -A birthday_to_names=(
['Sep-09']='abc def'
['Oct-11']='xyz'
)
names=${birthday_to_names[$(date %b-%d)]}
[[ $names ]] && printf 'Happy Birthday %s!\n' $names
Note that this version congratulates all birthday people if there are multiple names associated with the given birthday.