Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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

Example:

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?

share|improve this question
up vote 36 down vote accepted

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"
share|improve this answer
    
Thanks, had forgotten about sed. But to clarify, sed doesn't take the argument -E.. – Torandi Jul 22 '09 at 23:36
    
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 '09 at 23:40
1  
-r seems to to that for me. – Torandi Jul 22 '09 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 '12 at 1:38
2  
This doesn't work for multiline input. For that you need: sed -n "s/.*'\([^']\+\)'.*/\1/p" – phreakhead Oct 10 '12 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 "(?<=')[^']+(?=')"

share|improve this answer
4  
grep -P is not available on all platforms. But if it is, using lookahead/behind is a very nice way of solving the problem. – Sebastien Jun 13 '12 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? – Ross Rogers Oct 1 '12 at 18:33

You must log in to answer this question.

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