58

If I am doing several substitutions which need to be consecutive, e.g.

sed -i '/^[[:space:]]*browser.*\.should/s/browser/expect(browser/' t1_spec.rb
sed -i '/expect(browser.*\.should/s/\.should/).should/' t1_spec.rb
sed -i 's/\.should/\.to/' t1_spec.rb 
sed -i 's/==/eq/' t1_spec.rb 

Is there a better way to do this that will only go through the t1_spec.file once and do the the 4 substitutions for each line rather than going through the file 4 times?

3 Answers3

98

Beside using semicolons, you can also give more than one expression to sed by using the -e flag:

sed -i -e 's/expr1/replace1/' -e 's/expr2/replace2/'  t1_spec.rb 
jofel
  • 26,758
24

In GNU (e.g. on my Ubuntu machine), simply using multiple lines is supported and is inferred to mean multiple substitutions. It works well and looks good (imho) as it avoids super long lines, e.g.

sed -i '/^[[:space:]]*browser.*\.should/s/browser/expect(browser/
        /expect(browser.*\.should/s/\.should/).should/
        s/\.should/\.to/
        s/==/eq/' t1_spec.rb 
24

You can use semicolons to separate the different substitions between the single quotes

sed -i 's/foo/bar/;s/abc/def/' t1_spec.rb

or you can put all those commands in a file and specify the file with the -f option to sed.

sed -i -f my_sed_commands t1_spec.rb

Using the file is particularly useful if you are going to use the same set of sed commands over and over again. I used to have to deal with a dirty data feed and I ended up over time with an 88 line file called massage.sed to automatically clear out most of the common mistakes I got from the feed.

rogerdpack
  • 1,715
kurtm
  • 7,055