Awk Command – Ignoring Space as Delimiter

awkbashsed

I have a problem with my script.

Prelude
Firstly, I have a list, 100 lines-file like that:

100;TEST ONE
101;TEST TWO
...
200;TEST HUNDRED

Each line have 2 arguments.
For example, first line's arguments are: "645", "TEST ONE". So semicolon is a delimiter.

I need to put both arguments in two variables. Let's say it will be $id and $name.
For each line, $id and $name values will be different. For example, for second line $id = "646" and $name = "TEST TWO".

After that I need to take the sample file and change predefined keywords to $id and $name values.
Sample file looks like this:

xxx is yyy

And as a result I want to have 100 files with different content. Each file must contain $id and $name data from every line. And It must be named by it's $name value.

There is my script:

#!/bin/bash -x
rm -f output/*

for i in $(cat list)
    do

        id="$(printf "$i" | awk -F ';' '{print $1}')"
        name="$(printf "$i" | awk -F ';' '{print $2}')"

        cp sample.xml output/input.tmp

        sed -i -e "s/xxx/$id/g" output/input.tmp
        sed -i -e "s/yyy/$name/g" output/input.tmp

        mv output/input.tmp output/$name.xml


    done

So, I just try to read my list file line by line. For every line I'm getting two variables and then use them to replace keywords (xxx and yyy) from sample file and then save result.

But something went wrong

As a result I have only 1 output file. And debug is looking bad.

Here is debug window with only 2 lines in my list file.
I got only one output file.
File name is just "TEST" and it contain a string: "101 is TEST".

Two files expected: "TEST ONE", "TEST TWO" and it must contain "100 is TEST ONE" and "101 is TEST TWO".

debug screenshot

As you can see, second variable have a space in it ("TEST ONE" for example). I think the issue is related to the space special symbol, but I don't know why. I put -F awk parameter to ";", so awk must interpret only semicolon as a separator!

What I did wrong?

Best Answer

If I understand you correctly, you can use a while loop and variable expansion

while IFS= read -r line; do 
  id="${line%;*}"
  name="${line#*;}"
  cp sample.xml output/input.tmp
  sed -i -e "s/xxx/$id/g" output/input.tmp
  sed -i -e "s/yyy/$name/g" output/input.tmp
  mv output/input.tmp output/"$name".xml
done < file

As proposed by @steeldriver, here's a (more elegant) option:

while IFS=';' read -r id name; do 
  cp sample.xml output/input.tmp
  sed -i -e "s/xxx/$id/g" output/input.tmp
  sed -i -e "s/yyy/$name/g" output/input.tmp
  mv output/input.tmp output/"$name".xml
done < file
Related Question