Skip to main content
added 1091 characters in body
Source Link

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 ?!

/foo/{ does

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 ?

/foo/{ does

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 !

Source Link

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 ?

/foo/{ does