If we want to get the text between the 2 patterns excluding themselves.
Supppose we have the file **test.txt** containing :
blabla
blabla
foo
here
is the
text
to keep between the 2 patterns
bar
blabla
blabla
The following code can be used :
sed -n '/foo/{
n
b gotoloop
:loop
N
:gotoloop
/bar/!{
h
b loop
}
/bar/{
g
p
}
}' test.txt
For the following output :
here
is the
text
to keep between the 2 patterns
How does it work, let's make it step by step
1. `/foo/{` is triggered when line contains "foo"
2. `n` replace the pattern space with next line, i.e. the word "here"
3. `b gotoloop` branch to the label "gotoloop"
4. `:gotoloop` defines the label "gotoloop"
5. `/bar/!{` if the pattern doesn't contain "bar"
6. `h` replace the hold space with pattern, so "here" is saved in the hold space
7. `b loop` branch to the label "loop"
8. `:loop` defines the label "loop"
9. `N` appends the pattern to the hold space.
Now hold space contains :
"here"
"is the"
10. `:gotoloop` We are now at step 4, and loop until a line contains "bar"
11. `/bar/` loop is finished, "bar" has been found, it's the pattern space
12. `g` pattern space is replaced with hold space that contains all the lines between "foo" and "bar" that have saved during the main loop
13. `p` copy pattern space to standard output
Done !
[tag:sed] [tag:multiline] [tag:loop]