I got a bunch of files, and I want to find out the content between two tags st and et.
if I use grep "st.*et" files, I will get these two tags involved in the result.
Such as st Hello world! et.
But I just need the Hello world! part.

Is there a way to show only the content between the tags using grep(or other regex tools)?

PS: I know how to use tools such as AWK, python to do further-processing with these results to reach my goal. But I just wonder there could be a more direct way to do that.

  • 2
    Does your version of grep support PCRE mode? Commented Jun 12, 2015 at 3:20
  • Please edit your question and add i) your operating system, UNIX grep and GNU/Linux grep are very different; ii) an example of your input file and your desired output. What's a "tag"? Do you mean <st>? Or just the string st? Would foostbar count? Will the two "tags" always be on the same line or do you need to match across multiple lines?
    – terdon
    Commented Jun 12, 2015 at 10:19

2 Answers 2


Using GNU grep built with recent PCRE support:

echo 'st Hello world! et' | grep -oP "st\K.*?(?=et)"

The key here is to use the look-ahead and look-behind zero-length assertions.

\K     ==>  Look-behind assertion
(?=et) ==>  Look-ahead assertion

For more info, you could read here.

  • Possibly right before the limit of the irrelevance, but If I can suggest something grep -oP 'st\K.*(?=et)' would be of greater effect to show that it works. Also I don't understand the \s in place of the ` `, it's a space, so why don't just match a space?
    – kos
    Commented Jun 12, 2015 at 5:56
  • @kos Yep. You're right. Now, made it more relevant. I just quickly answered the question without giving much thought.
    – shivams
    Commented Jun 12, 2015 at 5:58

You may want to use sed:

sed -n 's/.*st\(.*\)et.*/\1/p'
  • This command searched the st content et pattern, and replaced it with ` content `, then printed it out. Nice trick. So, pure regex can't do what I'm looking for?
    – ZengJuchen
    Commented Jun 12, 2015 at 8:23
  • @Zen; Yes, "pure" (standard) regexp won't do that because you have a matching context that's not part of the desired result; so you need some means to strip your data from that surrounding context. - There's some extensions available in some tools that support it; have a look at the other answer for one (non-standard) way to address such a task.
    – Janis
    Commented Jun 12, 2015 at 9:05
  • @Zen a regex engine that supports lookarounds can do it perfectly well, we just can't be sure what tools you have available that support that unless you tell us your OS.
    – terdon
    Commented Jun 12, 2015 at 10:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .