grep man page

grep to output only needed capturing group

Say you have some text and some pattern that you want to provide for grep. Everything is easy, until you want to extract only the pattern-matching part, not the whole line that has the match. What to do?

You can “grep” and use pipe for further processing, like sed or awk. But did you know that you can do it solely with grep?

Say you have this data file:

[root@linux ~]# cat data.txt
foo 1 bar
bar 2 foo
foo 3 bar
bar 4 foo
[root@linux ~]#

And you want to grep number only from those lines that begin with “foo” and ends with “bar”:

[root@linux ~]# grep -Po "^foo\s([0-9]+)\sbar$" data.txt
foo 1 bar
foo 3 bar
[root@linux ~]#

You almost did it! Just… Your wish was only the number, nothing before and nothing after. So your wish is that output would be only your first capturing group. Use lookahead and lookbehind zero-length assertions to achieve it:

[root@linux ~]# grep -Po "^foo\s\K([0-9]+)(?=\sbar$)" data.txt
1
3
[root@linux ~]#

or:

[root@linux ~]# grep -Po "(?<=^foo\s)([0-9]+)(?=\sbar$)" data.txt
1
3
[root@linux ~]#