Reputation: 13
bash newbie here. I am trying to figure out how to read the email parts of a CSV files so that I can use it to email them the other items of the CSV. For instance (see sample CSV below), I will need to send [email protected] his order of fries,and burger.
Email,orders,Status
[email protected],fries,fulfilled
[email protected],burger,fulfilled
[email protected],soda,Not fulfilled
[email protected],soda,fulfilled
[email protected],burger,Not fulfilled
[email protected],fries,fulfilled
[email protected],soda,fulfilled
[email protected],burger,fulfilled
[email protected],fries,Not fulfilled
[email protected],soda,Not fulfilled
[email protected],fries,fulfilled
[email protected],burger,fulfilled
I am a bit of a loss on to where to actually begin. I have this:
cat "result.csv" | while IFS=',' read -r line; do
email="$(echo "$line" | cut -d ',' -f 1)"
order="$(echo "$line" | cut -d ',' -f 2)"
done
But I could not figure out how to advance 1 line to see if I need to include the order from the next line (if the email address is the same as what the script is currently reading.) Bash and python solutions are welcome :-)
Upvotes: 0
Views: 84
Reputation: 13747
I think what you're looking for is code to accumulate the order over lines. A more challenging task. Assuming you're using bash version 4 or higher, this will work. If you are on version 3 of bash, the final email address will be blank. I actually am using version 3 of bash (arg- Apple you suck), so I hope I got it right. I filled in the last line by hand.
#!/bin/bash
previous_email=""
full_order=""
IFS=,
(while read -r current_email order status; do
# echo $current_email $order $status
if [[ "$current_email" == 'Email' ]] ; then
previous_email="Email"
else
if [[ $current_email != $previous_email ]] ; then
# Destination email changed
if [[ $previous_email == "Email" ]] ; then
# Nothing to print from header line
previous_email=$current_email
if [[ "$status" == "fulfilled" ]]; then
full_order=$order
else
full_order=""
fi
else
# Do summary
if [[ $full_order == "" ]] ; then
printf "$previous_email - You have no orders\n"
else
printf "$previous_email - Your order is $full_order\n "
fi
previous_email=$current_email
if [[ "$status" == "fulfilled" ]]; then
full_order=$order
else
full_order=""
fi
fi
else # continue with same email
if [[ "$status" == "fulfilled" ]]; then
if [[ $full_order == "" ]] ; then
full_order=$order
else
full_order="$full_order, $order"
fi
fi
fi
fi
done < result.csv
printf "$current_email your order is $full_order\n" )
sh prog.sh
[email protected] - Your order is fries, burger
[email protected] - Your order is soda, fries
[email protected] - Your order is soda, burger
[email protected] - You have no orders
[email protected] your order is fries, burger
Upvotes: 0
Reputation: 530960
Your read
command would split the line, if you provided enough names to be assigned to.
while IFS=, read -r email order status; do
if [ "$status" != fulfilled ]; then
echo "$email ordered $order, but still awaiting delivery"
else
echo "$email received their $order"
fi
done < result.csv
In general, bash
can only handle simple CSV files like this, where there are no quoted commas. It is recommended to use a language with a proper CSV parsing library instead of bash
.
Upvotes: 2