4

I've got a file with a bunch of long lines. I'd like to grab every group between two patterns and print them to a new file, one match per line. I could manage to do this with Python, but I'd prefer using just command line tools for this task. If there is no end pattern, I'd like to grab everything 'till the end of the line.

Something like:

input: 
xxSTART relevanttext xxEND something else xxSTART even more relevant

output:
relevanttext
even more relevant
  • So START and END both are within the same long line? – iruvar Sep 26 '13 at 19:29
  • Yes! I used to have just one match per line, so I'd use sed to grab everything after xxSTART, but now the input data changed and I'm a bit stumped. – user48020 Sep 26 '13 at 19:30
6

IF GNU grep is an option, you could pass the -P (perl-compatible regex) flag and use lookahead assertions, lookbehind assertions and non-greedy matches to pull out what you need

echo 'xxSTART relevanttext xxEND something else xxSTART even more relevant'  |\
grep -oP '(?<=START).*?(?=xxEND|$)'
relevanttext
even more relevant

Or as Stephane Chazelas suggests, use the nifty \K in place of the look-behind assertion

echo 'xxSTART relevanttext xxEND something else xxSTART even more relevant'  |\
grep -oP 'START\K.*?(?=xxEND|$)' 
  • 1
    Or: grep -oP 'START\K.*?(?=xxEND|$)' – Stéphane Chazelas Sep 26 '13 at 20:27
  • @StephaneChazelas, that's a good point, added in. My version of GNU grep (2.5.1) doesn't support \K though – iruvar Sep 26 '13 at 20:35
  • 1
    That's more down to the version of libpcre grep was linked against than the version of grep itself. \K was added in pcre 7.2 (2007) (feature from perl 5.10) – Stéphane Chazelas Sep 26 '13 at 20:47

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.