# sed - how to exclude multiple patterns in the match

I have currently a set of seds that's working well except for one thing.

The particular expression I'm having an issue with is:

sed -i '/[^}.to]\.to[[:space:]]/ s/$$\S$$/expect(\1/' ../_spec_seded/"$file"  Right now this works fine. Basically it looks for .to and insert expect at the start of the expression. In particular, it excludes }.to when looking to match on .to which works. Now I want to also exclude 'this' or 'that' from the search match. In my case }.to or end.to i.e. instead of /[^}.to]\.to[[:space]]/  should I have: /[^}.to|^end\.to]\.to[[:space]]/ /[^}.to][^end\.to]\.to[[:space]]/ /[(^}.to|end\.to)]\.to[[:space]]/ /[^(}.to|end\.to)]\.to[[:space]]/  would I even need to escape parens if using them like /[^$$}.to|end\.to$$]\.to[[:space]]/  or even the | as well? /[^$$}.to\|end\.to$$]\.to[[:space]]/  I'm trying to make the match work on: stuff.to do thing stuff).to do thing this.to that all.all.all.to do pretend.do # Note this edge case! (pretend contains "end"!)  but not on this will be here }.to do last.end}.to do all.this at the end.to none at allend.to  and all.this at the end.to # i.e. no spaces before as it is the start of the line.  Negating with OR's generally (all languages) seems tricky (due to false positives). - What's the difference between the pretend.do and none at allend.to cases that one should match and the other shouldn't? And how come pretend.do matches when it doesn't have a \.to[[:space:]]? – Joseph R. Nov 10 '13 at 19:46 ## 2 Answers Pending your response to my comment on the question, here's my answer: • First of all, [^}.to] doesn't do what you seem to think. It will not match lines that don't have the pattern }.to. It matches lines that have any character other than ., }, t or o. In other words, many lines. • To make things easier, let's have sed print nothing by default then tell it to print everything except those lines matching the patterns you want to exclude: sed -n '/$$\bend\|}\.to$$/!p' your_file  This will print all lines not containing end.to at a word boundary (i.e. allend.to doesn't count) or }.to. If, in addition you want to print only those lines that match \.foo[[:space:]], simply delete lines matching unwanted patterns and add a conditional print: sed -n '/$$\bend\|}\.to$$/d;/\.to[[:space:]]/p' your_file  Of course, between the match and the print, you can apply whatever substitution you feel like: sed -n '/$$\bend\|}\.to$$/d;/\.to[[:space:]]/s/foo/bar/g;p' your_file  - Thanks Joseph, good info. – Michael Durrant Nov 10 '13 at 20:39 For most cases this seems to work: before: sed -i 's/[^}.to].to[[:space:]]/).to /' ../_spec_seded/"$file"


after:

sed -i 's/[^}.to|end.to].to[[:space:]]/).to /' ../_spec_seded/"\$file"

-