Multiple replacement

Hi friends

Hope, you all are doing well

I need your help for doing multiple strings replacement. I have a file with more than 1000 lines and I want to replace several elements in the same run. I have the equivalences written in another file.

Example: target file

Start (bp)	 End (bp)  Strand	Rank	Gene            ID	           Chromosome 
51066374	51066598	-1	1	ARSA	ENST00000356098	22
51063446	51063892	-1	8	ARSA	ENST00000216124	22
51064007	51064109	-1	8	ARSA	ENST00000395621	22
51063457	51063892	-1	8	ARSA	ENST00000453344	22

Example: equivalences file

ID	                        RefSeq
ENST00000216124	NM_000487
ENST00000547805	NM_001085425
ENST00000356098	NM_001085426
ENST00000395619	NM_001085427
ENST00000453344	NM_001085428

I'd like to replace "ID" strings by "RefSeq"

Thank you so much!

while IFS=" " read old new
do
sed "s/$old/$new/g" target_file > temp_file
mv temp_file target_file
done < equiv_file

Another way to do this using awk once instead of using sed once for each line in the equivalences file is:

awk '
BEGIN { OFS = "\t"}
FNR == NR {ID[$1] = $2;next}
{       if(FNR == 1) sub(/ID/, ID["ID"])
        else if($6 in ID) $6 = ID[$6]
        print
}' equivalences target

If you're using a Solaris/SunOS system, use /usr/xpg4/bin/awk , /usr/xpg6/bin/awk , or nawk instead of awk .

For the input files shown in the 1st message in this thread, the output produced is:

Start (bp)       End (bp)  Strand       Rank    Gene            RefSeq             Chromosome
51066374        51066598        -1      1       ARSA    NM_001085426    22
51063446        51063892        -1      8       ARSA    NM_000487       22
51064007        51064109        -1      8       ARSA    ENST00000395621 22
51063457        51063892        -1      8       ARSA    NM_001085428    22

To make Don's proposal a bit more flexible, you could introduce a variable for the column. If the header's fields do not contain FS chars, you can omit the extra treatment for line 1:

awk     'BEGIN          {FS = OFS = "\t"}
         FNR == NR      {ID[$1] = $2; next}
         $COL in ID     {$COL = ID[$COL]}
         1
        ' COL=6 equivalences target

Thank you so much guys!

Problem solved!
:b::b::b::b::b:

I looked at trying that, but decided against it since the header line contains a mix of spaces and tabs and the spaces around "ID" in the header line cause $6 = ID[$6] to skip the change of "ID" to "RefSeq" in the header.

Another solution:

xargs printf 's/\\b%s\\b/%s/;\n' <equiv_file >subst.pl
perl -p subst.pl target_file

\\b because the \b has a special meaning in printf.
\b in perl is "word boundary" and gives a more precise match.

perl -i -p subst.pl target_file

will directly modify target_file.
The following is even more precise here, because column 1 is not involved:

xargs printf 's/(\s)%s(\s)/$1%s$2/;\n' <equiv_file >subst.pl