Replace all occurrences of a string found in a file using values from another file

I have a CSV file (data.csv) as below:

apple_val, balloon_val, cherry_val, dog_val
1         ,5           ,6          ,7
3         ,19          ,2          ,3

I have a text file (sentence.txt) as below:

I have apple_val apple(s) and balloon_val balloons. My dog_val dogs were biting the cherry_val cherries. 

I want my output file (output.txt) as below:

I have 1 apple(s) and 5 balloons. My 7 dogs were biting the 6 cherries.
I have 3 apple(s) and 19 balloons. My 3 dogs were biting the 2 cherries. 

I used the below script. But my script is specific to the above example.

awk -F "," {print $1, $2, $3, $4} data.csv | while read a, b, c,d
do
    sed -e "s/apple_val/$a/g" -e "s/balloon_val/$b/g" -e "s/dog_val/$d/g" -e "s/cherry_val/$c/g" sentence.txt >> output.txt
done

I want to make it generic by reading the first line of the CSV file (the header) and replacing the occurrences of those strings (like apple_val) in the text file.

How can I do it?

Answer

Modified alienth variant (arrays is used):

#!/bin/bash
tr -s ',' ' ' <data.csv | {
read -a tokens
while read -a values; do
    for index in $(seq 0 $((${#tokens[*]}-1))); do
        echo "s/${tokens[$index]}/${values[$index]}/g"
    done | sed -f - sentence.txt
done
}

Same with awk:

awk -F"[, ]+" '
NR == FNR{
    s=s $0 "n"
    next}
FNR == 1{
    for(i=1;i<=NF;i++)
        val[i]=$i
    next}
{
    p=s
    for(i=1;i<=NF;i++)
        gsub(val[i], $i, p)
    printf p}
' sentence.txt data.csv

Leave a Reply

Your email address will not be published. Required fields are marked *