Shell script -How to group test file records based

2019-08-24 02:36发布

问题:

I have a comma separated csv file named "file1" with below details and the headers are.. incident number, date, person name and email id. The requirement is to group records by person name and send email listing all records by his or her name.

So in this example Sam, Mutthu, Andrew, Jordan will receive one email each and in that email they will see all records on their name.

10011,5-Jan,Sam,Sam@companydomain.com

10023,8-Jan,Mutthu,Mutthu@companydomain.com

10010,8-Jan,Mutthu,Mutthu@companydomain.com

10026,15-Jan,Sam,Sam@companydomain.com

10050,10-Jan,Jordan,Jordan@companydomain.com

10021,12-Jan,Andrew,Andrew@companydomain.com

I have searched the forum for solution but not able to map which solution to go with, all I can find below command to create separate files based in person name which will not fit in our requirement.

    awk -F\, '{print>$3}' file1

talking about our existing script, it sends email one by one using below command so it will send multiple emails to Mutthu and Sam which we don't want.

    /usr/sbin/sendmail -v $MAILTO $MAILCC |grep Sent >> "$HOME/maillog.txt"

Any Help will be appreciated

Thanks Shan

回答1:

As the question is tagged "bash", here a possible solution as a pure shell script. Note that this was not tested.

#!/bin/bash

MAILCC=x@y.com

in_file="file1"

# 1. grep all lines containing a '@' (contained in email address)
# 2. Cut field 4 (the email address)
# 3. sort uniq (remove duplicate email addresses)
#
# Loop over that list
#
for email in $(grep '@' $in_file | cut -d, -f 4 | sort -u); do
    # only if $email is a non-empty string
    if [ -n "$email" ]; then
        # grep for email in source file and mail found lines
        {
            echo "From: sender@example.net"
            echo "To: $email"
            echo "Subject: Your test file records"
            echo ""
            grep "$email"  $in_file | while read -r line; do
               echo "$line"
           done
        } | /usr/sbin/sendmail -v $email $MAILCC
    fi
done | grep Send >>"$HOME/maillog.txt"


回答2:

Here is an Awk script which does what you request. We collect the input into an array, where each element contains the lines for one recipient, and the key is the recipient's email address ($4). Finally we loop over the keys and send one message each.

awk -F , '{ a[$4] = a[$4] ORS $0 }
    END {
        for (user in a) {
            cmd = "/usr/sbin/sendmail -v " $4
            print "From: sender@example.net" | cmd
            print "To: " $4 | cmd
            print "Subject: stuff from CSV" | cmd
            # Neck between headers and email body
            print "" | cmd
            # Skip initial ORS
            print substr(a[user],2) | cmd
            close(cmd) } }' file.csv |
grep Sent >>"$HOME/maillog.txt"

I can't guess what's in MAILCC so I just left it off. If you always want to Cc: a static address, adding that back should be easy.



标签: bash shell unix