Storing data in shell - shell

I have a need to store a list of e-mails in a shell script. This script will get called and passed a customer number. depending on the customer number I want to populate a variable based on the passed in customer number.
I am not sure how to accomplish this and have been looking.
command example
gcb "type" "customernumber" "date"
I want to pull an e-mail associated with that customer number and populate a variable with it.
I would prefer this get stored in the script and not in a separate file if possible.
#shellter
So as you can see above my command has the customer number as $2, i am trying to get the email finder to work with that in mind. So I created a script to test the e-mail finder function with. It works fine as you have it below, but if i want it to look for $2 == cust_id it returns nothing. Here is my code below.
#!/bin/sh
#case $# in 0 ) echo "usage: myEmailFinder2 CustID" ; exit 1 ;; esac
cfgDir="/verification"
# given cust file like
# cust_id "\t" email_addr
fn_myEmailFinder() {
awk -F"\t" -v cust_id="$2" '{if ($2 == cust_id) {print $3}}' /verification/custlist.cfg
}
emailAddr=$( fn_myEmailFinder "$1")
echo $emailAddr
The command I run to test this is this
sh emailtest.sh test 90624
My config file is layed out like this, tab delimited
CustomerNumber CustomerName Email
I am going to store more data in this file to populate other variables, I'm sure once i get this figured out, I can sort out the other data.
I appreciate all of your help.

This script will get called and passed a customer number.
myEmailFinder "$CustID"
I want to populate a variable based on the passed in customer number.
emailAddr=$( myEmailFinder "$CustID")
I want to pull an e-mail associated with that customer number and populate a variable with it.
I would prefer this get stored in teh script and not in a separate file if possible.
Using a database is preferred, but .... per your written specification, try this
cat myEmailFinder
#!/bin/bash
case $# in 0 ) echo "usage: myEmailFinder CustID" ; exit 1 ;; esac
# given cust file like
# cust_id "\t" email_addr
fn_myEmailFinder() {
awk -F"\t" -v cust_id="$1" '{
if ($1 == cust_id) {
print $2
}
}' <<-EOF
1 user1#myCorp.com
2 user2#myCorp.com
5 user3#myCorp.com
EOF
#--^tabCh^---make sure you put a real tab char between custID and emailAddr
#tabCh-TabCh--- data indented with TabChars. EOS indented with **only** tabCh.
#send an email to cust in $1
emailAddr=$( fn_myEmailFinder "$1")
mailx -S "Test Email" "$emailAddr" <<-EOM
Here is the body of an email addressed to $emailAddr with CustID=$custID
EOM
#end of script
The block delimited by EOF is the place to store your custID and associated email Addresses. One per line, tab-delimited. The Indents on each line should be done with tab chars. The closing EOF line must be done ONLY with tab chars.
A preferable solution would be to store the "lookup table" in a separate file. That would look like
cat myEmailFinder2
#!/bin/bash
case $# in 0 ) echo "usage: myEmailFinder2 CustID" ; exit 1 ;; esac
cfgDir="/usr/local/data"
# given cust file like
# cust_id "\t" email_addr
fn_myEmailFinder() {
awk -F"\t" -v cust_id="$1" '{
if ($1 == cust_id) {
print $2
}
}' "$cfgDir"/emaillist.cfg
#send an email to cust in $1
emailAddr=$( fn_myEmailFinder "$1")
mailx -S "Test Email" "$emailAddr" <<-EOM
Here is the body of an email addressed to $emailAddr with CustID=$custID
EOM
where emaillist.cfg is laid out as above, tab-delimited.
IHTH

#!/bin/bash -
''''echo "Customer number: $1"
X=$(/bin/env python $0 $1)
echo $X
exit
'''
customers = {
42: 'customerA'
,43: 'customerB'
}
import sys
print customers.get(int(sys.argv[1]), '')
sys.exit(0)
:-|
if [ "$1" = "42" ]; then X="CustomerA" ; fi
if [ "$1" = "43" ]; then X="CustomerB" ; fi

Related

SED not adding a first line to .csv file

I am doing a project for school and my head has gone through 3 walls with how many times I have bashed it. the project is to ask a name and color and assign each to a variable then make a directory from the color variable in the /tmp directory. create a .csv file with header, pull the information from a given .txt file out of order and add only select columns. I have gotten to the point of adding the columns but no matter what i do I cant get sed to add a header or import the information from the .txt file.
as you can see i have tried multiple ways to modify the file but I dont know enough yet to make it work
the input file format is as follows
1. 734-44-2041 James SMITH jsmith#beltec.us 360-555-4778 360-555-0158
and it should look like
james,smith,james.smith#beltec.us,734-44-2041-000
I am assuming that the 3 commas are intended to be 0's at the end
this is the code I have so far
#!/bin/bash
#interactive=
#variables
color=/tmp/$color
csvfile=/tmp/blue/midterm.csv
if [ "$1" == "" ]; then
echo "you should use the -c or -C flags
exit
fi
#adding the -c flag and setting the filename variable
while [ "$1" != "" ]; do
case $1 in
-c | -C ) shift
filename=$1
;;
* ) echo "you should use the -c flag"
exit 1
esac
shift
done
#get user's name
echo "what is your name"
read user_name
#get fav color from user
echo "what is your favorate color"
read color
#make the fov color directory
if [ ! -f /tmp/$color ]; then
mkdir /tmp/$color
else
echo "bad luck $user_name"
exit 1
fi
#cd into the directory
cd /tmp/$color
#make a csv file in /temp/$color
touch midterm.csv
akw '
BEGIN { FS=OFS=","; print "Firstname","lastname","Maildomain","Password" }
{ print $2,$3,$4,$1 }
' "$filename" > "/tmp/$color/midterm.csv"
sed by default outputs its results on the standard output.
In case you need to overwrite the old file use -i (or better -i.bak) to keep previous file version in <filename>.bak
Moreover in case you need to add something only at the beginning of the file use following syntax:
sed '1iYOUR_TEXT'
You never need sed when you're using awk. All you need to create a header + content is:
awk '
BEGIN { FS=OFS=","; print "Firstname", "Lastname", "Maildomain", "Password" }
{ print $3, $4, $5, $2 }
' "$filename" > "/tmp/$color/midterm.csv"
Or if your input file isn't a CSV as it seems not to be by your updated question:
awk '
BEGIN { OFS=","; print "Firstname", "Lastname", "Maildomain", "Password" }
{ print $3, $4, $5, $2 }
' "$filename" > "/tmp/$color/midterm.csv"

Shell script -How to group test file records based on column value and send email to corresponding receipents.?

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
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"
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.

Awk print exact fields when finding an exact match

I have a persons.dat file containing information.
Here's an example line.
1129|Lepland|Carmen|female|1984-02-18|228T04:39:58.781+0000|81.25.252.111|Internet Explorer
1129 is the ID.
I am asked to display the information of anyone based on their ID,in particular their firstname (Carmen), (Lastname = Lepland) and date of Birth (1984-02-18) separated by a space.
I have stored the id in a shell variable IDNumber as shown below:
for arg1 in $#;do # Retrieve ID Number
if [ $1 = "-id" ];then
IDNumber="$2"
fi
shift
done
How can I use awk to display the exact fields of one ID?
The command line argument parsing of the shell script is a bit confusing like that, since arg1 is not used.
And even after it finds -id and assigns $2 to IDNumber,
the iteration continues.
For example when the arguments are -id 3,
after IDNumber=3,
the iteration continues, checking if [ 3 = "-id" ].
Also, the "$1" in if [ $1 = ... ] should be double-quoted,
otherwise the script will crash if there is an empty argument.
Here's one way to fix these issues:
while [ $# -gt 0 ]; do
if [ "$1" = -id ]; then
id=$2
fi
shift
done
Then you can use id with Awk like this:
awk -F'|' -v id="$id" '$1 == id {print $3, $2, $5}' persons.dat
That is:
Set | as the field separator
Set id variable in Awk to the value of $id in the shell
Find the record in the input where the first field ($1) is equal to id
Print the columns you need

How to send an E-mail with AWK using the SYSTEM command

So I have this uni homework where I need to send an E-mail to all the people from a certain group of students (which are listed in the diak.lst file) and to attach the text from a file to the mail as well. The address of the students is in a similar form: xy9999, 2 characters and 4 numbers.
The problem seems to be at the SYSTEM part, it says that there is no such thing as "attachedfile".
The diak.lst is in the following format:
F-Name,Name,Address,Group
George Peter gp9999 511
This is the script
#!/bin/bash
if [ ! -f $2 ]
then echo $2 Not a file!!
exit 1
fi
awk -v group=$1 -v attachedfile=$2 'BEGIN {fs=" ";nr_sent_to=0;}
{
if ($4==group){
system("mail -s \"Attention!\"" $3 " < " attachedfile);
nr_sent_to++;
}
}
END {
print nr_sent_to,"-have received the mail";
}
' diak.lst
You dont have a space before $3 in the string mail sees- try changing \"Attention!\"" $3 to \"Attention!\" " $3.
You have fs=" " which does nothing. Maybe you mean FS=" " but that's the default value so it will do nothing.
Your input file has a comma-separated header line so when processing that $3 etc. will be blank, add a NR>1 clause.
awk vars already init to 0/NULL so no need for nr_sent_to=0. You do have to then add +0 when printing it in the END section to make sure the number zero instead of the NULL string is printed if/when no emails are sent.
Given that everything you are doing in the BEGIN section is doing nothing useful, get rid of the BEGIN section.
Won't affect the script execution but: awk is not C - lose all the useless trailing semi-colons.
Put conditions in the condition part of the script, not the action part.
Quote your shell variables.
So with a bit more cleanup the end result would be:
awk -v group="$1" -v attachedfile="$2" '
NR>1 && ($4==group) {
system("mail -s \"Attention!\" " $3 " < " attachedfile)
nr_sent_to++
}
END {
print nr_sent_to+0, "-have received the mail"
}
' diak.lst

How to display text file in columns using bashscript in unix?

I am making a bash script contact list system. This is what it prints out.
=================
Menu
=================
Enter 1 for Insert new contact
Enter 2 for Print current contact list
Enter 3 for Search contact list
Enter 4 for Exit
Enter your selection:
For "1" it ask for name, email, and phone and stores them for variables then stores them in a text file.
case "$answer" in
1) echo -e "Enter in a new contact name: \c"
read name
echo -e "Enter in new contact email address: \c"
read email
echo -e "Enter in new contact phone number: \c"
read phone
echo "$name, $email, $phone" >> contacts.txt ;;
For 2 is where I am having trouble. I want to display the text in three columns so I can sort them by name, email, or phone number. This is my code for case 2.
2) cat contacts.txt ;;
Obviously it only spits out:
Test Name, Test#data.com, 123-123-1234
Blank Data, Data#aol.com, 234-555-5555
I want it to read:
Name Email Phone
Test Name Test#data.com 123-123-1234
Blank Data Data#aol.com 234-555-5555
How would I do that? And how would I be able to sort it later on?
Change
echo "$name, $email, $phone" >> contacts.txt ;;
to
echo "$name,$email,$phone" >> contacts.txt ;;
and try this:
(echo Name,Email,Phone; cat contacts.txt) | column -s , -t
$ cat contacts.txt
Test Name, Test#data.com, 123-123-1234
Blank Data, Data#aol.com, 234-555-5555
$ awk -F, 'BEGIN{printf "%-12s %-15s %-12s\n","Name"," Email"," Phone"} {printf "%-12s %-15s %-12s\n",$1,$2,$3}' contacts.txt
Name Email Phone
Test Name Test#data.com 123-123-1234
Blank Data Data#aol.com 234-555-5555
How it works:
The printf statement allows custom formatting of output. Above the format string %-12s %-15s %-12s\n was used. Taking %-12s, for example, the 12s part means that we want to format a string to a width of 12 columns. The minus sign means that we want that field left-justified.
Looking at each piece of the awk code separately:
-F,
This tells awk to use a comma as the field separator on each line.
BEGIN{printf "%-12s %-15s %-12s\n","Name"," Email"," Phone"}
The BEGIN block is executed before the first line of the file is read. It is used here to print the header.
printf "%-12s %-15s %-12s\n",$1,$2,$3
awk implicitly loops through every line in the file. For each line, we print out the first three fields as per the format statement.

Resources