Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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
add comment

4 Answers

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
add comment

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
add comment

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
add comment
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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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