Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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).

share|improve this question
    
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 2

up vote 2 down vote accepted

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

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.