Find and replace wildcard that spans across lines?

724 Views Asked by At

I would like to input some text like this:

foo
stuff
various stuff
could be anything here
variable number of lines
bar
Stuff I want to keep
More stuff I want to Keep
These line breaks are important

and get out this:

 foo
 teststuff
 bar
 Stuff I want to keep
 More stuff I want to Keep
 These line breaks are important

So far I've read and messed around with using sed, grep, and pcregrep and not been able to make it work. It looks like I could probably do such a thing with Vim, but I've never used Vim before and it looks like a royal pain.

Stuff I've tried includes:

sed -e s/foo.*bar/teststuff/g -i file.txt

and

pcregrep -M 'foo\s+bar\s' file.txt | xargs sed 's/foo.*bar/teststuff/g'

I'm not sure if it's just that I'm not using these commands correctly, or if I'm using the wrong tool. It's hard for me to believe that there is no way to use the terminal to find and replace wildcards that span lines.

3

There are 3 best solutions below

0
Ed Morton On BEST ANSWER

For clarity, simplicity, robustness, maintainability, portability and most other desirable qualities of software, just use awk:

$ awk 'f&&/bar/{print "teststuff";f=0} !f; /foo/{f=1}' file
foo
teststuff
bar
Stuff I want to keep
More stuff I want to Keep
These line breaks are important
3
Cyrus On

Try this with GNU sed:

sed -e '/^foo/,/^bar/{/^foo/b;/^bar/{i teststuff' -e 'b};d}'

See: man sed

0
potong On

This might work for you (GNU sed):

sed '/foo/,/bar/cteststuff' file

This will replace everything between foo and bar with teststuff.

However what you appear to want is everything following foo before bar, perhaps:

sed '/foo/,/bar/cfoo\nteststuff\nbar' file