Home > Software design >  Using AWK to substitute
Using AWK to substitute

Time:02-10

First time attempting to tinker with AWK and use it to take input from a file like the following:

data.csv

James,Jones,30,Mr,Main St
Melissa,Greene,200,Mrs,Wall St
Robert,Krupp,410,Mr,Random St

and process it into a LaTeX Template

data.tex

\newcommand{\customertitle}{XYZ} %ggf. \
\newcommand{\customerName}{Max Sample} % Name \
\newcommand{\customerStreet}{Str} % Street \
\newcommand{\customerZIP}{12345} % ZIP

First I tried to replace the customer name this way

awk 'BEGIN{FS=","}{print $1 " " $2 }' data.csv | xargs -I{} sed "s/Max Sample/{}/" data.tex > names

which gave me a merged file.. and therefore I subsequently attempted to render the file as single .tex files by inserting a keyword "#TEST" at the end of the original file, so I could use it as a Record Separator to get me back to single files with the following command:

awk 'BEGIN {FS=RS="#TEST"} {i=1}{ while (i <= NF) {print $i >>"final"NR".tex"; i  }}' names

Even though that worked for this one field, for multiple fields it doesn't seem to be a proper solution as is though. (title, street, zip code)

That's why I'm now attempting to get it working with the gsub action in AWK.
Tried those different approaches. Based on what I could find regarding it thus far, that's what I came up with:

awk 'BEGIN {FS=","}NR==FNR{a[FNR]=$4;next}{gsub ("XYZ",a[FNR]);print}' data.csv data.tex

which replaces XYZ with nothing

awk 'BEGIN {FS=","}NR==FNR{a[FNR]=$4;next}RS="#TEST"{for (i in a) {gsub("XYZ",i);print}}' data.csv data.tex \

which counts four times to 7

Tried those also with the merged file, ie. the "names" output from the first command and didn't get it to work.
What am I missing? Can the gsub command not replace a string with an array? Is a loop required?

I'm stuck, hope someone can help out here

CodePudding user response:

I hope it is your case. Create a file csv_to_latex.awk and put this code:

BEGIN{
    FS=","
    while(getline < latex > 0) {
    
        lax_array[$0]
    }
}
    
{
    name = $1" "$2
    zip = $3
    status = $4
    street = $5

    for (lax_key in lax_array)
    {    
        if (lax_key ~ /XYZ/)
        {
            gsub("{XYZ}", "{"status"}", lax_key)
            print lax_key
        }
        else if (lax_key ~ /Max Sample/)
        {
            gsub("{Max Sample}", "{"name"}", lax_key)
            print lax_key
        }
        else if (lax_key ~ /Str/)
        {
            gsub("{Str}", "{"street"}", lax_key)
            print lax_key
        }
        else if (lax_key ~ /12345/)
        {
            gsub("{12345}", "{"zip"}", lax_key)
            print lax_key
        }
    }
}

To execute this code, use in terminal:

awk -v latex="data.tex" -f csv_to_latex.awk data.csv

The output:

\newcommand{\customertitle}{Mr} %ggf. \
\newcommand{\customerName}{James Jones} % Name \
\newcommand{\customerStreet}{Main St} % Street \
\newcommand{\customerZIP}{30} % ZIP
\newcommand{\customertitle}{Mrs} %ggf. \
\newcommand{\customerName}{Melissa Greene} % Name \
\newcommand{\customerStreet}{Wall St} % Street \
\newcommand{\customerZIP}{200} % ZIP
\newcommand{\customertitle}{Mr} %ggf. \
\newcommand{\customerName}{Robert Krupp} % Name \
\newcommand{\customerStreet}{Random St} % Street \
\newcommand{\customerZIP}{410} % ZIP

CodePudding user response:

I feel like doing replaces is unnecessary and would probably approach it like this:

awk -F, -v po='\\newcommand{\\%s}{%s} %s \n' '{
    printf po, "customertitle", $4, "%ggf. \\"
    printf po, "customerName", $1" "$2, "% Name \\"
    printf po, "customerStreet", $NF, "% Street \\"
    printf po, "customerZip", $3, "% Zip"
}' data.csv

output:

\newcommand{\customertitle}{Mr} %ggf. \
\newcommand{\customerName}{James Jones} % Name \
\newcommand{\customerStreet}{Main St} % Street \
\newcommand{\customerZip}{30} % Zip
\newcommand{\customertitle}{Mrs} %ggf. \
\newcommand{\customerName}{Melissa Greene} % Name \
\newcommand{\customerStreet}{Wall St} % Street \
\newcommand{\customerZip}{200} % Zip
\newcommand{\customertitle}{Mr} %ggf. \
\newcommand{\customerName}{Robert Krupp} % Name \
\newcommand{\customerStreet}{Random St} % Street \
\newcommand{\customerZip}{410} % Zip
  • Related