I have a file which has (many) strings I'd like to replace, so I thought about using a simple command like:

sed 's/string1/string2/g' file1 > out  

However, there are too many strings for that to be repeated manually. So I made a list of all the strings to be replaced, each in a line, and named it file A. Then I made a list of all the replacement strings, and named it file B.

Is there a way to do something like:

sed 's/line i of file A/line i of file B/g' file1 > out

for each line of file A?


It would be easier to create a file with both the input and replacement strings on the same line (assuming that neither input nor replacement strings contain spaces). Then you can do so something simple like:

while read n k; do sed -i "s/$n/$k/g" file1; done < fileA


After seeing Nykakin's answer, I realized you can do the same thing with the two files you have combining his suggestion with mine:

paste fileA fileB | while read n k; do sed -i "s/$n/$k/g" file1; done 
  • +1, this answer is simpler than mine and doesn't require subshell. – Nykakin Jan 12 '13 at 1:38
  • 1
    NIce, this worked! just in my case I needed to use double quotes ("s/$n/$k/g" instead of 's/$n/$k/g') Also, if it helps anybody I'd name the files like this: fileA --> replace_what fileB --> replace_with file1 --> file_to_process ^^ – aesede Jul 1 '15 at 21:19

This is basically your first idea, but with the substitution commands put into a file, so they’re more manageable:

exec 3< fileA
exec 4< fileB
while read –r astring <&3
        read –r bstring <&4
        echo "s/$astring/$bstring/" >> "$tmpfile"
exec 3<&- 4<&-
sed –f "$tmpfile" file1 > out
rm –f "$tmpfile"

This assumes that fileA and fileB have the same number of lines (and that that number is greater than zero) and that neither of them has any unescaped / characters.


We can just generate command that we need. Let's say that files with lists are called lista and listb. Then we can use:

$ for i in $(paste lista listb -d/); do echo -n "-e 's/$i/g' "; done

to generate option for sed. Now we can use it with eval. Let's say our file is called test. We use:

$ eval "sed" $(for i in $(paste lista listb -d/); do echo -n "-e 's/$i/g' "; done) "test"
  • You don't need the eval (see my answer) but +1 for paste, I hadn't thought of that. – terdon Jan 12 '13 at 1:35
paste -d : fileA fileB | sed 's/\([^:]*\):\([^:]*\)/s%\1%\2%/' > sed.script
sed -f  sed.script SOURCE-FILE

SOURCE-FILE may be either an individual file or multiple files. The text in fileA and fileB cannot contain either colon or percent characters, but may contain blank characters.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.