The first grep will get all the lines that contain Foo as well as the line after the match. Then we get lines that contain Bar as well as the line before the match, and finally extract the lines from this output that contain Foo.

EDIT: As manatwork pointed out, there are some problematic cases to be observant of. Although an interesting challenge, due to grep's line oriented functionality, any solution with it is likely to be a 'hack' and you are probably better off using something like pcregrep which is more suited to the task at hand.

Cool trick what -z. Some “(.*)” before and after the whole expression would make it output the entire matched lines. For now substrings before “Foo” and after “Bar” are not displayed.
–
manatworkOct 9 '12 at 8:19