prokopio_kuba
prokopio_kuba

Reputation: 13

Parsing CSV and storing values into variables

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

Answers (2)

Leonard
Leonard

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

chepner
chepner

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

Related Questions