Read Field from file1 and find and replace in file2

Hi All,

I have file1 line below:

$myName$|xxx

Now I need to read the file1 and find for $myName$ in file2 and replace with xxx

file1:

$myName$|xxx

file2:

My name is $myName$

expected output in file2 after executing the script is below:

my name is xxx

Thanks,

The $ char you have chosen for your marker makes it harder, as is is a meta char and means something to gsub.

Anyway here is an solution in awk:

awk -F\| 'NR==FNR{A=$1; gsub("\\$", "\\$", A); rep[A]=$2; next;}
{ for(r in rep) gsub(r, rep[r],$0);
  print $0 }' file1 file2

Here is solution with %% or # markers instead:

awk -F\| 'NR==FNR{rep[$1]=$2; next;}
{ for(r in rep) gsub(r, rep[r],$0);
  print $0 }' file1 file2

Hi gdevadas,

Try with:

awk 'NR==FNR{gsub(/\|/," ");a[$1]=$1;b[$1]=$2;next}{c[$4]=$4;d[$4]=$1" "$2" "$3}
END{for(i in c) if(c==a) print d,b; else print d,c}' file1 file2

Hope it helps.

Regards.

@cgkmal, didn't work too well with my test files (didn't expand my markers, changed order of lines and truncated first line):

file1

$myName$|xxx
$myAge$|21
$myShell$|/bin/bash

file2

My name is $myName$, and I'm $myAge$ years old.
I love $myShell$

output

I love $myShell$ 
My name is $myName$,

Hi Chubler,

This change order issue is something what I was seeing how to solve in the printing when I do for(i in X), but I can't so far :wall:.

The other thing, I see now that I was testing with fixed format files format and not more general files as you show. Certainly it won't work
only with my simple test files:(. I'll try to adapt it in some other way if I can in order to work with other files:confused:

Your first code works fine with my test files, but the 2nd code prints the same file2, as below:

$ cat file1
$myName$|xxx
$yourName1$|xxy
$hisName$|zzz

$ cat file2
Your name is $yourName$
My name is $myName$
His name is $hisName$

$ awk -F\| 'NR==FNR{rep[$1]=$2; next;}
{ for(r in rep) gsub(r, rep[r],$0);
  print $0 }' file1 file2
Your name is $yourName$
My name is $myName$
His name is $hisName$

Regards

Thanks a lot for your valuable point. As suggested by you we will replace the $ into @ symbol.

Now my requirement is little bit changed and I explained it below in detail:

  1. ConfigFile

File1|@Name@|XXXX
File2|@Phone@|1234
File3|@Age@|25

Now the I need to read this config file and then I need to get the file in first column and need to find the value in second column in the file and then I need to replace it.

Please help me to write the snippet for this also please suggest some link to get the complete understanding about awk. I am beginner in UNIX

Not real clear what you are after here. Some sssumptions I've made:

  1. The order the files are output should remain the same as defined in config file
  2. Multiple replaces may appear for each file
  3. Replace tag (eg @Phone@) may have different values for different files

Here is the solution in awk:

awk -F\| '{if(!($1 in F))P[++f]=$1;F[$1];R[$1,$2]=$3}
END{
   for(i=1;i<=f;i++)  {
     while((getline < P) > 0) {
         for(idx in R) {
            split(idx,val,SUBSEP);
            if(val[1]==P) gsub(val[2],R[idx]);
         }
         print $0
     }
     close(P)
   }
}' ConfigFile
1 Like

This is fantastic and awesome..... Chubler many thanks for you....... :b::b::b::b:

Your assumption is perfect and this is what I want...

Finally one more kind request. I want to replace the values into files and I need to save the files with replaced values. Could you please help me in that......

Again Thanks for the snippet .....:slight_smile:

---------- Post updated 04-07-11 at 10:11 AM ---------- Previous update was 04-06-11 at 08:03 PM ----------

Hello Chubler,

I am waiting for your response.......

Thans,

How about this:

OLDIFS="$IFS"
IFS=\|
while read file fromval toval
do
   sed -i "s/$fromval/$toval/g" "$file"
done < ConfigFile
IFS=$OLDIFS