sed -n '/start/,/end/ p'
Yesterday, I needed to search roughly a thousand files to see if a certain string occurred between two other strings on different lines. I could have written a Perl/Python/Ruby script to do this. Heck, I could have done it with a one-liner, but that would have required shifting mental gears. Instead I chose a solution that required little more than a knowledge of vi and some simple command line tools.
Vi and sed are both based on ed. Most of the things you can do at the : prompt in vi you can also do with sed. One cool thing you can do is addressing. For example, the following vi command will search for the word "cat" and replace it with the word "dog", but only if it occurs between a line containing "foo" and a line containing "bar":
:/foo/,/bar/s/cat/dog/g
What would that look like with sed? I'll show you in a moment, but first I want to explain why my next version is more complicated.
I find extended regular expressions easier to work with, so I'm going to use sed -e. It'd probably be best to handle both "Cat" and "cat". Because I'm performing multiple search and replace commands, I also need to use { } for grouping. I only want to replace "[Cc]at" with "[Dd]og" if the word is by itself, not if it's a substring of another word, so I'm going to need to use the word anchor \b. And so, without further ado, here's a sed command that does all that:
sed '/foo/,/bar/ { s/\bcat\b/dog/g ; s/\bCat\b/Dog/g }' file.txt
In the case of my problem yesterday, I didn't need to do any search and replace. I just needed to print every line between the two pattern. Because I didn't care about the name of the file where the pattern occurred. The solution was a simple as:
sed -n '/foo/,/bar/ p' *.dat| grep --color=auto something
If I had cared about which files contained the pattern, I could have done something like this:
for I in *.dat
do
(sed -n '/foo/,/bar/ p' "$I" | grep something) &> /dev/null &&\
printf "\n-----\n$I\n-----\n" && \
sed -n '/foo/,/bar/ p' "$I"
done
I don't feel like explaining that particular command, so deciphering it is left as an excercise for the reader.