I have a file where every line is a new customers information, such as

Pop corn, pop@gmail.com, 50, 200

I am currently trying to see if it is possible to use a awk/gawk script to assign each column to a variable and then pipe those variables to sed to be substituted into a template? I would be running both awk/gawk and sed from within a bash script. What is a good implementation I could follow to get this done? I'm trying not to use grep, because I'm trying to learn how to cohesively use awk/gawk, sed, and bash scripts together or perl since I haven't learned it yet.

  • Do you want to assign each column to a shell variable or to an awk variable? – Satō Katsura Oct 2 '17 at 3:39
  • I thought I would go ahead at first at use awk variables if it was possible (which I now know is), if it were not then I would have tried using variables declared with in the bash script and exporting them to awk. – below_avg_st Oct 2 '17 at 3:43
  • Depending on the specifics, it may be that you don't need sed, or that you don't need the shell variable to do your templating, or even awk. Since you only give minimal info about what it is you actually want to do ("substitute (something) into a template"), it's difficult to give a "good implementation" for anything other than the parsing of the file that you talk about at the start. – Kusalananda Oct 2 '17 at 5:25

It seems to me you should be better off doing something like:

while IFS=, read -r name email x y _ignored_; do
  email=${email# } x=${x# } y=${y# }
  sendmail -oem -oi -t << EOF
To: $name <$email>
Subject: Whatever

x=$x y=$y
done < file.csv

That, is since you're going to run at least one command per line anyway, use the shell to read the lines into variables. And use shell variable expansion in the here-document instead of sed to do the template expansion.

awk wouldn't help much here as while it can run commands with its system() or getline() (but via running a shell to parse a command line), it cannot set environment variables for those, other than building the shell code that sets those variables. So, it would become quite convoluted and less efficient. Something like:

CODE='sendmail -oem -oi -t << EOF
to: $name <$email>
Subject: Whatever

x=$x y=$y
EOF' awk -F ', *' -v q="'" '
  function shquote(s) {
    gsub(q, q "\\" q q, s)
    return q s q
  {system("name="shquote($1)" email="shquote($2)" x="shquote($3) \
          " y="shquote($4)"\n"ENVIRON["CODE"])}' < file.csv

Use split function of awk to read the line into the array with specific delimiter.

awk '{split($0, array, /,/)}' customers_file

Then you can pass to sed what elements of this array you want to feed it with just printing those elements within awk.

  • is this pearl? or is split also an implementation in bash/awk? – below_avg_st Oct 2 '17 at 4:33
  • Hi, this is awk and split is its built in function. – αғsнιη Oct 2 '17 at 4:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.