Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question

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

EDIT:

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 
share|improve this answer
    
+1, this answer is simpler than mine and doesn't require subshell. – Nykakin Jan 12 '13 at 1:38
    
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:

tmpfile=/tmp/Asasuser.$$
exec 3< fileA
exec 4< fileB
while read –r astring <&3
do
        read –r bstring <&4
        echo "s/$astring/$bstring/" >> "$tmpfile"
done
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.

share|improve this answer

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"
share|improve this answer
    
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.

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .