0

My file1 looks like:

bla bla bla STRING_1 blabla STRING_2.
bla bla bla bla bla.

My file2 looks like (tab-separated):

FILENAME   FIELD_1   FIELD_2
out1   ABCDEF   GHIJKL
out2   MNOPQR   STUVWX

I am trying to replace STRING_1 and STRING_2 from file1 with the corresponding fields from file2, and output 2 different files with their name as below:

out1:

bla bla bla ABCDEF blabla GHIJKL.
bla bla bla bla bla.

out2:

bla bla bla MNOPQR blabla STUVWX.
bla bla bla bla bla.

What I tried:

awk -F '\t' '
NR==FNR{
   if(NR>1){
      a[NR]=$1
      b[NR]=$2
      c[NR]=$3
      next
   }
}
{
   for(i=1; i<=FNR; i++){
      gsub(/STRING_1/,bi])
      gsub(/STRING_2/,c[i])
      print $0 > a[i]
   }
}
' file2.tab file1.tab

This command only creates a file "FILENAME" that contains the following:

bla bla bla FIELD_1 blabla FIELD_2.
bla bla bla bla bla.

Any help would be appreciated. Thanks !

NOTE: file1 is a unique template file for which the content does not change.

2 Answers 2

1

Here's how to implement your approach of using gsub()s, untested:

awk '
NR==FNR {
    if (NR>1) {
        files[$1]
        for (i=2; i<=NF; i++) {
            map[$1,i-1] = $i
        }
    }
    next
}
{
    for (file in files) {
        rec = $0
        gsub(/STRING_1/,map[file,1],rec)
        gsub(/STRING_2/,map[file,2],rec)
        print rec > file
    }
}
' file2 file2

Note that this approach will have problems if STRING_1, etc. can contain regexp metacharacters, or if the replacement ones can contain backreferences (&), or if partial matches are possible (the replaced within then). You may also need to close() the output files as you go and use >> to write to them if you have many output files and aren't using GNU awk.

Sign up to request clarification or add additional context in comments.

Comments

0

GNU awk solution:

awk 'NR==FNR{ 
         if (NR==1) next;
         c=0; f[$1][++c]=$2; f[$1][++c]=$3; next 
     }
     { 
         c=0;
         for (i in f) { 
             b[++c]=$0; 
             gsub(/STRING_1/, f[i][1], b[c]); 
             gsub(/STRING_2/, f[i][2], b[c]); 
             print b[c] > i 
         }
     }' file2 file1
  • f[$1][++c] - multidimensional array f where $1 is a parent key (for ex. out1) and ++c points to ordinal field number (i.e. 1 and 2)
  • for (i in f) - iterating through output filenames

Viewing results:

$ head out[12]
==> out1 <==
bla bla bla ABCDEF blabla GHIJKL.
bla bla bla bla bla.

==> out2 <==
bla bla bla MNOPQR blabla STUVWX.
bla bla bla bla bla.

2 Comments

@EdMorton, try without it and you'll see
No, that's fine, I don;t care enough to try it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.