解析CSV并将值存储到变量中

时间:2018-09-25 15:38:06

标签: bash

这里是bash新手。我试图弄清楚如何读取CSV文件的电子邮件部分,以便可以用它通过电子邮件将CSV的其他项目发送给他们。例如(请参阅下面的CSV示例),我将需要将他的薯条和汉堡订单发送到email1@domain.com。

Email,orders,Status
email1@domain.com,fries,fulfilled
email1@domain.com,burger,fulfilled
email1@domain.com,soda,Not fulfilled
email2@domain.com,soda,fulfilled
email2@domain.com,burger,Not fulfilled
email2@domain.com,fries,fulfilled
email3@domain.com,soda,fulfilled
email3@domain.com,burger,fulfilled
email4@domain.com,fries,Not fulfilled
email5@domain.com,soda,Not fulfilled
email5@domain.com,fries,fulfilled
email5@domain.com,burger,fulfilled

我对真正从哪里开始有点迷茫。我有这个:

cat "result.csv" | while IFS=',' read -r line; do
  email="$(echo "$line" | cut -d ',' -f 1)"
  order="$(echo "$line" | cut -d ',' -f 2)"
done

但是我不知道如何前进1行以查看是否需要从下一行开始输入顺序(如果电子邮件地址与脚本当前正在读取的地址相同)。欢迎使用Bash和python解决方案:-)

2 个答案:

答案 0 :(得分:2)

如果您提供了足够的名称来分配,您的read命令将拆分行。

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

通常,bash仅能处理像这样的简单CSV文件,其中没有引号。建议使用具有适当CSV解析库的语言,而不要使用bash

答案 1 :(得分:0)

我认为您正在寻找的是用于累积行数的代码。一个更具挑战性的任务。假设您使用的bash版本4或更高版本,则可以使用。如果您使用的是bash版本3,则最终的电子邮件地址将为空白。我实际上正在使用bash的版本3(arg- Apple,您很烂),所以我希望我做对了。我手动填写了最后一行。

#!/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
email1@domain.com  - Your order is fries, burger
email2@domain.com  - Your order is soda, fries
email3@domain.com  - Your order is soda, burger
email4@domain.com  - You have no orders
email5@domain.com  your order is fries, burger