Is it possible to use GNU grep to get a matched group from an expression?


echo "foo 'bar'" | grep -oE "'([^']+)'"

Which would output "'bar'". But I would like to get just "bar", without having to send it through grep one more time (ie. get the matched group). Is that possible?

3 Answers 3


You can use sed for this. On BSD sed:

echo "foo 'bar'" | sed -E "s/.*'([^']+)'.*/\\1/"

Or, without the -E option:

sed "s/.*'\([^']\+\)'.*/\1/"

This doesn't work for multiline input. For that you need:

sed -n "s/.*'\([^']\+\)'.*/\1/p"
  • 1
    Hm, it does on my machine (Mac OS X). Upon further examination, in the man page: "The -E, -a and -i options are non-standard FreeBSD extensions and may not be available on other operating systems."
    – jtbandes
    Jul 22, 2009 at 23:40
  • 1
    It's similar to grep's -E: "Interpret regular expressions as extended (modern) regular expressions rather than basic regular expressions (BRE's). The re_format(7) manual page fully describes both formats."
    – jtbandes
    Jul 22, 2009 at 23:44
  • 1
    -r seems to to that for me.
    – Torandi
    Jul 22, 2009 at 23:46
  • 1
    @jtbandes: You don't need the extended features for this expression.. I just requires 3 escape characters for ( ) + use \( \) \+: This is effectively the same: sed "s/.*'\([^']\+\)'.*/\1/"
    – Peter.O
    Jan 11, 2012 at 1:38
  • 3
    This doesn't work for multiline input. For that you need: sed -n "s/.*'\([^']\+\)'.*/\1/p"
    – phreakhead
    Oct 10, 2012 at 18:15

While grep can't output a specific group, you can use lookahead and behind assertions to achieve what your after:

echo "foo 'bar'" | grep -Po "(?<=')[^']+(?=')"

  • 10
    grep -P is not available on all platforms. But if it is, using lookahead/behind is a very nice way of solving the problem.
    – Sébastien
    Jun 13, 2012 at 13:16
  • 1
    Is grep intelligent with the look-behind assertions? How does it perform with long look-behinds? Is it integrating the look-behinds into some sort of "suffix tree" with the rest of the regex? Oct 1, 2012 at 18:33
  • Literally an article I accidentally found related to this example: franklingu.github.io/programming/2016/11/19/…
    – Faither
    Jun 8, 2021 at 7:16

You can use \K to reset and discard the left hand match text along with a lookahead which is not added to the match text:

$ echo "foo 'bar'" | grep -oP "'\K[^']+(?=')"

GNU grep only.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.