0

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.

Stonecraft
  • 860
  • 1
  • 12
  • 30

3 Answers3

1

Try this with GNU sed:

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

See: man sed

Cyrus
  • 84,225
  • 14
  • 89
  • 153
  • Yes, that works, thank you. I'm pretty sure I wouldn't have figured that out from the man page though. For some reason Sed seems especially cryptic to me. – Stonecraft Aug 23 '15 at 08:10
  • ..However it doesn't work when there is more text on the lines with foo and bar. Using that same code with `foo and more stuff various stuff variable number of lines with a bar Stuff I want to keep More stuff I want to Keep These line breaks are important ` gives this: `foo and more` Is there some general way that I can set up a wildcard in sed that will find absolutely anything and everything between the two specified strings? I can re-ask the question if need be, since it seems that the example I created wasn't generic enough. – Stonecraft Aug 23 '15 at 09:06
  • Please start a new question. Thank you. – Cyrus Aug 23 '15 at 09:18
1

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
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
0

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
potong
  • 55,640
  • 6
  • 51
  • 83